如何检测单元格值改变datagridview的C#单元格、datagridview

2023-09-04 22:58:01 作者:㈠娕玖違旳陽洸

似乎没有要对SOF类似的问题一个明确的答案。

我有一个的DataGridView 绑定到一个的BindingList< T> 对象(这是自定义列表对象;也继承了 INotifyPropertyChanged的)。自定义对象都有一个独特的计时器。当这些计时器的传递一定的值(比如10秒),我想细胞的前景色变为红色。

我现在用的是 CellValueChanged 事件,而这一事件似乎永远不会火,即使我能看到计时器改变在的DataGridView 。是否有不同的事件我应该寻找?下面是我的 CellValueChanged 处理程序。

 私人无效checkTimerThreshold(对象发件人,DataGridViewCellEventArgs E)
    {
        时间跨度TS =新的时间跨度(0,0,10);
        如果(e.ColumnIndex℃,|| e.RowIndex℃下)
            返回;
        如果(orderObjectMapping [dataGridView1的[订单ID,e.RowIndex] .Value.ToString()] getElapsedStatusTime()的CompareTo(TS)> 0)
        {
            的DataGridViewCellStyle cellStyle =新的DataGridViewCellStyle();
            cellStyle.ForeColor = Color.Red;
            dataGridView1.Rows [e.RowIndex] .Cells [e.ColumnIndex] .Style = cellStyle;
        }
    }
 

解决方案

有没有办法这个我知道,使在DataGridView引发一个事件时,它的数据源是一个编程改变 - 这是由设计

我能想到的,以满足您的要求,最好的办法是引入的BindingSource到混合 - 结合来源做引发事件时,他们的数据源的变化

像这样的作品(你会明显需要微调到你的需求):

  bindingSource1.DataSource = TBDATA;
dataGridView1.DataSource = bindingSource1;
bindingSource1.ListChanged + =新ListChangedEventHandler(bindingSource1_ListChanged);

公共无效bindingSource1_ListChanged(对象发件人,ListChangedEventArgs E)
{
    的DataGridViewCellStyle cellStyle =新的DataGridViewCellStyle();
    cellStyle.ForeColor = Color.Red;

    dataGridView1.Rows [e.NewIndex] .Cells [e.PropertyDescriptor.Name] .Style = cellStyle;
}
 

另一种选择,以通过直接订阅的数据这样做 - 如果它是一个的BindingList它将使用自己ListChanged事件propogate的NotifyPropertyChanged事件。在更MVVM的情况,将有可能成为清洁,但在的WinForms BindingSource的可能是最好的。

Excel单元格中的绿色三角很烦人,有木有

There does not seem to be a definitive answer for similar questions on SOF.

I have a DataGridView that is bound to a BindingList<T> object (which is a list of custom objects; also inherits INotifyPropertyChanged). The custom objects each have a unique timer. When those timer's pass a certain value (say 10 seconds), I want to change the cell's forecolor to red.

I am using the CellValueChanged event, but this event never seems to fire, even though I can see the timer changing on the DataGridView. Is there a different event I should be looking for? Below is my CellValueChanged handler.

private void checkTimerThreshold(object sender, DataGridViewCellEventArgs e)
    {
        TimeSpan ts = new TimeSpan(0,0,10);
        if (e.ColumnIndex < 0 || e.RowIndex < 0)
            return;
        if (orderObjectMapping[dataGridView1["OrderID", e.RowIndex].Value.ToString()].getElapsedStatusTime().CompareTo(ts) > 0)
        {
            DataGridViewCellStyle cellStyle = new DataGridViewCellStyle();
            cellStyle.ForeColor = Color.Red;
            dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Style = cellStyle;
        }
    }

解决方案

There is no way this I know of to make the DataGridView raise an event when its DataSource is programatically changed - this is by design.

The best way I can think of to meet your requirement is to introduce a BindingSource into the mix - binding sources do raise events when their DataSource changes.

Something like this works (you will obviously need to fine tune it to your needs):

bindingSource1.DataSource = tbData;
dataGridView1.DataSource = bindingSource1;
bindingSource1.ListChanged += new ListChangedEventHandler(bindingSource1_ListChanged); 

public void bindingSource1_ListChanged(object sender, ListChangedEventArgs e)
{
    DataGridViewCellStyle cellStyle = new DataGridViewCellStyle(); 
    cellStyle.ForeColor = Color.Red;

    dataGridView1.Rows[e.NewIndex].Cells[e.PropertyDescriptor.Name].Style = cellStyle;
}

Another option to to do this by subscribing directly to the data - if it is a BindingList it will propogate the NotifyPropertyChanged events using its own ListChanged event. In a more MVVM scenario that would possibly be cleaner but in WinForms the BindingSource is probably best.