【问题标题】:ObservableCollection does not update to DataGrid row unless all items in row are redefined [duplicate]除非重新定义行中的所有项目,否则 ObservableCollection 不会更新到 DataGrid 行 [重复]
【发布时间】:2019-11-24 06:02:19
【问题描述】:

我有一个绑定到 DataGrid 的结构的 ObservableCollection TableRows

public class TableStruct
{
    public string Item1 {get; set;}
    public string Item2 {get; set;}
    public string Item3 {get; set;}
    public string Item4 {get; set;}
    public string Item5 {get; set;}
    public string Item6 {get; set;}
}

当尝试连续更新单个项目时,我尝试这样做:

for(int i = 0; i < TableRows.Count; i++)
{
    if(SomeConditional)
    {
        TableStruct new_row = TableRows[i];
        new_row.Item3 = "changed";
        TableRows[i] = new_row;
    }
}

但是在运行程序时,DataGrid 没有更新。但是运行此代码确实会更新到 DataGrid 并按预期工作:

for(int i = 0; i < TableRows.Count; i++)
{
    if(SomeConditional)
    {
        TableStruct new_row = new TableStruct();
        new_row.Item1 = "same";
        new_row.Item2 = "same";
        new_row.Item3 = "changed";
        new_row.Item4 = "same";
        new_row.Item5 = "same";
        new_row.Item6 = "same";
        TableRows[i] = new_row;
    }
}

这里有什么不同?在我看来,它们都完成了相同的任务,但一个比另一个多行。

【问题讨论】:

  • TableStruct 应该实现INotifyPropertyChanged
  • 显然是因为 ObservableCollection 观察的是自身的变化而不是它的元素
  • 您的班级TableStruct 是否实施INotifyPropertyChanged?我认为您的第一个示例中发生的情况是没有发送更改通知。在第二个示例中,您实际上是在替换 TableRows 中的一项,这会导致更改通知。
  • 重要的区别是第一种情况是TableRows[i] = TableRows[i],而第二种情况是TableRows[i] = new TableStruct()。第一种情况被 ObservableCollection 忽略。

标签: c# wpf


【解决方案1】:

TableStruct 应该实现INotifyPropertyChanged

public class TableStruct : INotifyPropertyChanged
{
    private string _item3;
    public string Item3
    {
        get { return _item3; }
        set { _item3 = value; NotifyPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;  
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    //...
}

如果您通过在所有 setter 中调用 NotifyPropertyChanged() 方法来引发 PropertyChanged 事件,则可以直接设置 TableStruct 的属性以更新 UI:

for (int i = 0; i<TableRows.Count; i++)
{
    if (SomeConditional)
    {
        TableRows[i].Item3 = "changed";
    }
}

当项目的属性发生更改时,ObservableCollection&lt;T&gt; 不会通知 UI。它只通知集合中正在添加、删除或移动的项目。

【讨论】:

    猜你喜欢
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    • 2021-06-11
    • 2016-11-18
    • 2010-11-24
    • 2017-11-21
    • 2019-03-16
    相关资源
    最近更新 更多