如何根据列DataPropertyName访问DataRowView中的单元格?

时间:2011-01-25 11:45:07

标签: c# winforms datagridview

我有一个带有DataSet的Windows窗体应用程序。我只是使用了Data |添加New DataSource以将Northwind数据库的Products表添加到我的DataSources并创建一个显示Products表内容的DataGridView。我只是将Products表从Data Sources窗口拖到窗体中,因此所有列都是自动创建的。

现在,我希望包含Discontinued列为true的产品的行以不同的颜色绘制。我为它创建了一个CellPainting事件处理程序,但是我无法找到Discontinued列的值。

由于DataGridView是自动创建的,因此其中的列的名称类似于dataGridViewTextBoxColumn1,其DataPropertyName为“ProductID”。

我的问题是:如何根据DataPropertyName找到已停用的值?或者我是否需要使用列本身的名称? (在这种情况下,我最好给它一个有意义的名字)

我的代码是:

private void productsDataGridView_CellPainting(object sender,
    DataGridViewCellPaintingEventArgs e)
{
    if (e.RowIndex >= 0)
    {
        var row = productsDataGridView.Rows[e.RowIndex];
        if ((bool) (row.Cells[ nameOrIndexOfColumn ].Value))
        {
            e.CellStyle.ForeColor = Color.DarkGray;
        }
    }
}

如何使用DataPropertyName“已停止”来访问列的值?


解决方案

根据Neil Barnwell的回答,这似乎是一种方式。

private void productsDataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.RowIndex >= 0)
    {
        var productView = (DataRowView) productsDataGridView.Rows[e.RowIndex].DataBoundItem;
        var product = productView.Row as NorthwindDataSet.ProductsRow;
        if (product != null && product.Discontinued)
        {
            e.CellStyle.ForeColor = Color.DarkGray;
        }
    }
}

这样做的一大优点是Discontinued值不一定是DataGridView上的实际列。

3 个答案:

答案 0 :(得分:1)

不要从网格中的列中获取值,从填充gridrow的实际数据行中获取值。这样你就可以避免所有魔法字符串等。

由于[Type]DataRow隐藏在附加到网格的DataView内部,因此需要进行一些投射,但它是一种更优雅的方法(并且在未来的情况下更不易碎)如果你将它很好地集成到你的代码中,而不是依赖于魔术字符串。

这是我的一篇旧帖子,详细描述了如何做到这一点:

http://koder.wordpress.com/2010/04/09/getting-data-from-a-winforms-datagridview/

<强>更新
你已经提到过你正在使用Northwind并且你“简单地将Products表拖到了表单中”,所以我猜这不是一个关键任务软件,而是为了其他人的利益阅读,我只是想建议在实际应用中这不再是典型的方法。

通常这些天我们考虑使用Domain Model,可能使用ORM从数据存储中获取域对象(当然数据集不是真正的ORM),然后可能使用像MVVM之类的东西来构建数据结构,这些数据结构已经过优化,可以绑定到那些域对象的UI元素。

使用这种方法,因为您可以在ViewModel中提供实际数据,您可以从实际数据中计算颜色等规则,UI只显示应用这些业务规则的结果。

答案 1 :(得分:1)

为什么不尝试自己为该特定列命名,然后知道如何访问它。即使自动生成,Visual Studio也不应该有任何问题。因为它是为了帮助您在后台完成所有绑定和列创建工作而生成的。 它仍然可供编辑,自动生成并不意味着它在运行时生成。它只是帮助你做通常的事情,但你仍然可以编辑它。

row.Cells[ nameOrIndexOfColumn ]

答案 2 :(得分:0)

你可以尝试这些方面的东西

if (dataGridView1.Columns[e.ColumnIndex].DataPropertyName == "Discontinued")
{
  if (dataGridView1[reqdColumnIndex, e.RowIndex].FormattedValue as bool)
  {
    e.CellStyle.ForeColor = Color.Gray;
  }
}

reqdColumnIndex是具有bool值的列