C# DataGridView - 由 DataSource 引起的单元格更改事件

Posted

技术标签:

【中文标题】C# DataGridView - 由 DataSource 引起的单元格更改事件【英文标题】:C# DataGridView - event for Cell changes caused by DataSource 【发布时间】:2017-02-13 16:33:43 【问题描述】:

当 DataGridView 中的单元格值由于 DataSource 的变化而发生变化时,是否存在事件?

我创建了自己的自定义类来实现 INotifyPropertyChanged,

public class CustomWorkbook : INotifyPropertyChanged

    string filepath;
    string status;
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    
        if (PropertyChanged != null)
        
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        
    

    ...

并将其绑定到我的 DataGridView,如下所示,

BindingList<CustomWorkbook> workbookList = new BindingList<CustomWorkbook>();
BindingSource workbookBinding = new BindingSource(workbookList , null);
dataGridViewWorkbooks.DataSource = workbookBinding;

目前单元格值会根据需要自动更新,但我想添加更多处理和美学效果,这些效果需要知道单元格值何时发生变化以及哪个单元格(即使更新的单元格变为绿色,待处理的单元格变为黄色)

我已经尝试过 DataGridView 中的 CellValueChanged 事件,但这似乎只适用于用户编辑。 NotifyPropertyChanged 事件将在值发生更改时触发……但它不会对已更改的单元格提供任何引用。

【问题讨论】:

【参考方案1】:

在对大多数DataGridView 事件采取暴力处理方法后,我发现DataBindingComplete 事件正是我所追求的。每当我的 CustomWorkbook 类中的属性发生更改时,就会引发此事件(我假设 INotifyPropertyChanged 在我的 DataGridView? 中滴流到 BindingListBindingSource,最后是 DataSource?)。

虽然此事件没有为更改的属性提供对相应单元格的任何引用,但我最终只是循环遍历所有单元格,因为我知道包含相关单元格的列的名称。

    /// <summary>
    /// Called whenever changes have been made to the binded list
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void DataGridViews_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    
        DataGridViews_UpdateStatusColour(sender as DataGridView);
    

    /// <summary>
    /// Change the colour of the cells in the column whose DataPropertyName is "Status"
    /// </summary>
    /// <param name="grid"></param>
    private void DataGridViews_UpdateStatusColour(DataGridView grid)
    
        // Get the column index
        int targetColumn = 0;
        foreach (DataGridViewColumn col in grid.Columns)
        
            if (col.DataPropertyName == "Status")
            
                targetColumn = col.Index;
                break;
            
        

        // Loop through every row, and colour the corresponding cell
        foreach (DataGridViewRow row in grid.Rows)
        
            DataGridViewCell cell = row.Cells[targetColumn];
            switch (cell.Value.toString())
            
                case ("UPDATED"):
                    cell.Style.BackColor = System.Drawing.Color.Green;
                    cell.Style.SelectionBackColor = System.Drawing.Color.Green;
                    break;
                case ("PENDING"):
                    cell.Style.BackColor = System.Drawing.Color.Orange;
                    cell.Style.SelectionBackColor = System.Drawing.Color.Orange;
                    break;
                case ("MISSING"):
                    cell.Style.BackColor = System.Drawing.Color.LightSalmon;
                    cell.Style.SelectionBackColor = System.Drawing.Color.LightSalmon;
                    break;
                case ("ERROR"):
                    cell.Style.BackColor = System.Drawing.Color.Red;
                    cell.Style.SelectionBackColor = System.Drawing.Color.Red;
                    break;
                default:
                    break;
            
        
    

它的样子:

【讨论】:

您可能需要查看 DataGridView 属性 SelectedCells 和 CurrentCell - 这可能会帮助您缩小已编辑的单元格范围。 非常感谢您的回答!我在我的问题 (***.com/questions/59533784/…) 中寻找解决方案,但没有人相信我这是一个问题。我只是希望它实际上返回了已更改的单元格...

以上是关于C# DataGridView - 由 DataSource 引起的单元格更改事件的主要内容,如果未能解决你的问题,请参考以下文章

C# WinForm DataGridView 过滤器暂停

Datagridview 不显示数据

DataGridVIew 填充匿名类型,如何过滤?

C# 如何反序列化简单结构中的 json DATAS 数组?

C#里使用linq做多个值的GroupBy操作,被操作对象类型为List<Dictionary<string, string>> datas

c#设置datagridview行标题