An ObservableCollection
将通知更改。没有理由手动执行此操作,因此您可以删除所有OnPropertyChanged("JobEntities");
。这将使您获得更清洁的解决方案。
MSDN
WPF 提供了 ObservableCollection 类,它是一个内置的
数据收集的实施
INotifyCollectionChanged 接口。
下一部分是 ObservableCollection 将仅通知集合本身的更改(添加/删除)。对列表中元素的任何修改都不会发送通知消息。为此,最简单的方法是实现INotifyPropertyChanged
可观察集合中使用的元素
我在示例中使用的是 PRISM 5,因此它应该与您正在做的非常相同。您的代码有几个主要的设计更改。首先,我为我的可观察集合使用直接属性。我们知道框架将处理对此集合的任何添加/删除操作。然后,为了在更改可观察集合中的实体内的属性时发出通知,我在TestEntity
类本身。
public class MainWindowViewModel : BindableBase
{
//Notice no OnPropertyChange, just a property
public ObservableCollection<TestEntity> TestEntities { get; set; }
public MainWindowViewModel()
: base()
{
this.TestEntities = new ObservableCollection<TestEntity> {
new TestEntity { Name = "Test", Count=0},
new TestEntity { Name = "Test1", Count=1},
new TestEntity { Name = "Test2", Count=2},
new TestEntity { Name = "Test3", Count=3}
};
this.UpCommand = new DelegateCommand(this.MoveUp);
}
public ICommand UpCommand { get; private set; }
private void MoveUp()
{
//Here is a dummy edit to show the modification of a element within the observable collection
var i = this.TestEntities.FirstOrDefault();
i.Count = 5;
}
}
这是我的实体,注意BindableBase
以及我通知变更的事实。这允许DataGrid
或您用来通知属性更改的任何内容。
public class TestEntity : BindableBase {
private String _name;
public String Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
//Notice I've implemented the OnPropertyNotify (Prism uses SetProperty, but it's the same thing)
private Int32 _count;
public Int32 Count
{
get { return _count; }
set { SetProperty(ref _count, value); }
}
}
现在真的所有TestEntity
需要实施INotifyPropertyChanged
为此,但我使用的是 PRISMBindableBase
举个例子。
EDIT
我在 SO 上发现了类似的问题。我认为你的略有不同,但它们在概念上重叠。查看一下可能会有所帮助。
Observable Collection 当 MVVM 中的属性发生更改时发出通知
EDIT
如果数据网格已排序,则先前的方法将不会更新网格。要处理此问题,您需要刷新网格视图,但无法使用 MVVM 直接访问它。因此,要处理这个问题,您需要使用CollectionViewSource
.
public class MainWindowViewModel : BindableBase
{
//This will bind to the DataGrid instead of the TestEntities
public CollectionViewSource ViewSource { get; set; }
//Notice no OnPropertyChange, just a property
public ObservableCollection<TestEntity> TestEntities { get; set; }
public MainWindowViewModel()
: base()
{
this.TestEntities = new ObservableCollection<TestEntity> {
new TestEntity { Name = "Test", Count=0},
new TestEntity { Name = "Test1", Count=1},
new TestEntity { Name = "Test2", Count=2},
new TestEntity { Name = "Test3", Count=3}
};
this.UpCommand = new DelegateCommand(this.MoveUp);
//Initialize the view source and set the source to your observable collection
this.ViewSource = new CollectionViewSource();
ViewSource.Source = this.TestEntities;
}
public ICommand UpCommand { get; private set; }
private void MoveUp()
{
//Here is a dummy edit to show the modification of a element within the observable collection
var i = this.TestEntities.FirstOrDefault();
i.Count = 5;
//Now anytime you want the datagrid to refresh you can call this.
ViewSource.View.Refresh();
}
}
The TestEntity
类没有改变,但又是这个类:
public class TestEntity : BindableBase
{
private String _name;
public String Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
//Notice I've implemented the OnPropertyNotify (Prism uses SetProperty, but it's the same thing)
private Int32 _count;
public Int32 Count
{
get { return _count; }
set { SetProperty(ref _count, value); }
}
}
为了澄清起见,这是我的 XAML,显示了与新的绑定CollectionViewSource
.
<DataGrid Grid.Row="1" ItemsSource="{Binding ViewSource.View}"></DataGrid>
如需进一步阅读,您可以参考MSDN关于此的文章。
这是另一个相关问题/答案 -绑定数据更改后重新排序 WPF DataGrid