首页 文章

C#DataGridView - 由DataSource引起的Cell更改事件

提问于
浏览
1

由于DataSource中的更改,是否存在DataGridView中单元格值更改的事件?

我已经创建了自己的实现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

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

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

1 回答

  • 1

    在采用蛮力方法将事件处理程序添加到大多数 DataGridView 事件之后,我发现 DataBindingComplete 事件就是我所追求的 . 每当我的 CustomWorkbook 类中的属性发生更改时,都会引发此事件(我假设 INotifyPropertyChanged 涓流到 BindingListBindingSource ,最后 DataSource 在我的 DataGridView ?) .

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

    /// <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 with colour

相关问题