Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何基于列DataPropertyName访问DataRowView中的单元格?_C#_Winforms_Datagridview - Fatal编程技术网

C# 如何基于列DataPropertyName访问DataRowView中的单元格?

C# 如何基于列DataPropertyName访问DataRowView中的单元格?,c#,winforms,datagridview,C#,Winforms,Datagridview,我有一个带有数据集的Windows窗体应用程序。我只是使用数据|添加新数据源将Northwind数据库的Products表添加到我的数据源中,并创建了一个显示Products表内容的DataGridView。我只是将Products表从Data Sources窗口拖到表单中,所以所有列都是自动创建的 现在,我希望包含一个产品的行(其中非连续列为true)以不同的颜色绘制。我已经为它创建了一个CellPainting事件处理程序,但是我很难找到中止列的值 由于DataGridView是自动创建的,

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

现在,我希望包含一个产品的行(其中非连续列为true)以不同的颜色绘制。我已经为它创建了一个
CellPainting
事件处理程序,但是我很难找到中止列的值

由于
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
“已中断”的列的值


解决方案

根据尼尔·巴恩韦尔的回答,这似乎是一种方法

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;
        }
    }
}

这样做的最大优点是,不连续的值不必是DataGridView上的实际列。

不要从网格中的列获取值,而是从填充gridrow的实际datarow获取值。这样你可以避免所有的魔术弦等

由于
[Type]DataRow
隐藏在连接到网格的
DataView
中,因此需要进行一点转换,但是如果您将它很好地集成到代码中,而不是依赖于神奇的字符串,那么这是一种更优雅的方法(并且在将来发生更改时不会太脆弱)

下面是我的一篇老博文,详细描述了如何做到这一点:

更新
您提到您使用的是Northwind,并且您“只是将Products表拖到表单中”,因此我猜这不是一个任务关键型软件,但为了让其他人阅读,我只是想建议,在实际应用程序中,这不再是一种典型的方法

通常我们考虑使用A,也许使用AN从数据存储中获取我们的域对象(当然数据集不是真实的ORM),然后可能使用类似于构建用于绑定到来自域对象的UI元素的数据结构。
使用这种方法,因为您的ViewModel中有实际数据,所以您可以根据实际数据计算颜色等规则,UI只显示应用这些业务规则的结果。

您可以在这些行上尝试一些东西

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

reqdColumnIndex是具有布尔值的列

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

row.Cells[ nameOrIndexOfColumn ]

问题恰恰是如何找到正确的列。所以我不知道
reqdColumnIndex
。好吧,这是一个相当多的铸造过程。很遗憾,您首先必须将DataGridViewRow强制转换为DataRowView,然后将其Row属性强制转换为所需的DataRow类型。但不管怎样,你的帖子确实帮助了我。我会将我的C#实现添加到我的答案中,并将您的答案标记为答案。很高兴它有所帮助。需要投是一种耻辱,但据我所知,这是必要的。当然,您可以通过缓存等方式对其进行优化,但本质上这就是要采取的方法。这就是我所说的“或者我需要使用列本身的名称吗?(在这种情况下,我最好给它一个有意义的名称)”。除非您想进行编码冒险,否则您只需命名列即可。。这就是name属性存在的原因。;-)