WPF数据绑定:更新ObservableCollection中的项目

时间:2013-12-09 21:05:57

标签: c# wpf data-binding observablecollection

我试图在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;
}

1 个答案:

答案 0 :(得分:1)

INotifyPropertyChanged对象中Item的实施尚未完成。实际上FirstName属性没有变更通知。 FirstName属性应为:

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