【问题标题】:WPF Databinding: Updating an Item in an ObservableCollectionWPF 数据绑定:更新 ObservableCollection 中的项目
【发布时间】:2013-12-09 21:05:57
【问题描述】:

我试图在 WPF DataGrid 中反映 ObservableCollection 的更改。列表的添加和删除效果很好,但我一直在编辑。

我在构造函数中初始化 ObservableCollection:

public MainWindow()
{
    this.InitializeComponent();

    this.itemList = new ObservableCollection<Item>();
    DataGrid.ItemsSource = this.itemList;
    DataGrid.DataContext = this.itemList;
}

我有一个实现 INotifyPropertyChanged 的​​类:

public class Item : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public string FirstName { get; set; }

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = this.PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

ObservableCollection 的添加效果很好:

Application.Current.Dispatcher.Invoke((Action) (() => this.itemList.Add(new Item { FirstName = firstName })));

TL;DR

我的问题是,如何在允许数据绑定更新我的 GridView 的同时更新列表中的项目?

我无法实现它,除非可耻地删除并重新添加该项目:

item.FirstName = newFirstName;
Application.Current.Dispatcher.Invoke((Action)(() => this.itemList.Remove(item)));
Application.Current.Dispatcher.Invoke((Action)(() => this.itemList.Add(item)));

更新

根据评论请求,这里有更多关于我如何进行更新的代码:

foreach (var thisItem in this.itemList)
{
    var item = thisItem;

    if (string.IsNullOrEmpty(item.FirstName))
    {
        continue;
    }

    var newFirstName = "Joe";

    item.FirstName = newFirstName; // If I stop here, the collection updates but not the UI. Updating the UI happens with the below calls.

    Application.Current.Dispatcher.Invoke((Action)(() => this.itemList.Remove(item)));
    Application.Current.Dispatcher.Invoke((Action)(() => this.itemList.Add(item)));

    break;
}

【问题讨论】:

  • 显示更新是如何完成的
  • 我在更新中附加了一个代码示例。

标签: c# wpf data-binding observablecollection


【解决方案1】:

INotifyPropertyChanged 在您的 Item 对象中的实现不完整。 FirstName 属性实际上没有更改通知。 FirstName 属性应该是:

private string _firstName;
public string FirstName 
{ 
    get{return _firstName;}
    set
    {
        if (_firstName == value) return;
        _firstName = value;
        OnPropertyChanged("FirstName");
    }
}

【讨论】:

  • 触及属性命名。为了安抚我自己的困惑,我刚刚更新了我的示例并将属性重命名为FirstName
  • 不接触,只是在网络编辑器中写了这个,所以没有验证。试图通过肉眼验证,我看到的只是_valueValue_valuevalueValue。不是大人物,只是有趣(因此是笑脸)。使用 VS/R# 验证,这根本不是问题。
  • 效果很好!希望您不介意,我编辑了您的答案以匹配我对问题所做的更改。 Value 让我很困惑!
  • 太棒了!我已经批准了编辑并删除了关于命名的评论(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
  • 2014-11-11
  • 1970-01-01
  • 2021-01-24
  • 2010-11-29
  • 2016-02-21
相关资源
最近更新 更多