WPF DataGrid:如何对 SelectedItem 的属性进行数据绑定以触发 INotifyPropertyChangedEvents?
我正在尝试尽可能使用 MVVM 来做到这一点:
我的模型 (InterestTypeEntity) 实现了 INotifyPropertyChanged。
我的 ViewModel (InterestTypeAllViewModel) 有一个绑定到 DataGrid 的 ObservableCollection。当对其进行更改时,它将这些更改(添加/删除)发送到数据库。
问题是,当集合中对象的属性发生变化时,我还希望能够更新数据库。我不知道该怎么做?到目前为止,这是我的代码...
XAML:
<DataGrid Name="TestGrid" Grid.Row="3" Grid.ColumnSpan="2" AutoGenerateColumns="False"
ItemsSource="{Binding IntTypes}" SelectedItem="{Binding CurrentIntType}">
<DataGrid.Columns>
<DataGridTextColumn Header="Interest ID" Binding="{Binding IntType}" />
<DataGridTextColumn Header="Interested Parties Description" Binding="{Binding Description}" MaxWidth="500" />
</DataGrid.Columns>
</DataGrid>
ViewModel 代码:
public ObservableCollection<InterestTypeEntity> IntTypes
{
get { return DataRepository.InterestTypeEntities; }
}
public InterestTypeEntity CurrentIntType { get; set; }
public Int16 IntType
{
get { return CurrentIntType.IntType; }
set
{
if (value != CurrentIntType.IntType)
{
CurrentIntType.IntType = value;
OnPropertyChanged("IntType");
}
}
}
public String Description
{
get { return CurrentIntType.Description; }
set
{
if (value != CurrentIntType.Description)
{
CurrentIntType.Description = value;
OnPropertyChanged("Description");
}
}
}
I'm trying to do this as MVVM as possible:
My Model (InterestTypeEntity) implements INotifyPropertyChanged.
My ViewModel (InterestTypeAllViewModel) has an ObservableCollection that binds to a DataGrid. When changes are made to it, it sends those changes (add/remove) to the Database.
the problem is, I want to also be able to update the database when the properties of the objects within the collection change. I'm not sure how to do that? Here's my code so far...
XAML:
<DataGrid Name="TestGrid" Grid.Row="3" Grid.ColumnSpan="2" AutoGenerateColumns="False"
ItemsSource="{Binding IntTypes}" SelectedItem="{Binding CurrentIntType}">
<DataGrid.Columns>
<DataGridTextColumn Header="Interest ID" Binding="{Binding IntType}" />
<DataGridTextColumn Header="Interested Parties Description" Binding="{Binding Description}" MaxWidth="500" />
</DataGrid.Columns>
</DataGrid>
ViewModel Code:
public ObservableCollection<InterestTypeEntity> IntTypes
{
get { return DataRepository.InterestTypeEntities; }
}
public InterestTypeEntity CurrentIntType { get; set; }
public Int16 IntType
{
get { return CurrentIntType.IntType; }
set
{
if (value != CurrentIntType.IntType)
{
CurrentIntType.IntType = value;
OnPropertyChanged("IntType");
}
}
}
public String Description
{
get { return CurrentIntType.Description; }
set
{
if (value != CurrentIntType.Description)
{
CurrentIntType.Description = value;
OnPropertyChanged("Description");
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不要创建模型对象的集合,也不要在(当前)视图模型上实现
IntType
和Description
属性。除非您有其他原因这样做,否则不要在模型中实现属性更改通知。相反,使
IntTypes
成为InterestTypeEntityViewModel
对象的集合。此类包装了
InterestTypeEntity
。它公开IntType
和Description
属性,a) 包装底层InterestTypeEntity
属性,b) 执行属性更改通知。如果您使其构造函数采用InterestTypeEntity
参数,则可以轻松在视图模型中填充:将
ItemsSource
绑定到此集合。 (此外,将CurrentIntType
设为InterestTypeEntityViewModel
类型的属性,并在其更改时引发PropertyChanged
。)编辑:
如果当其集合中的项目的属性发生更改时,需要通知拥有视图模型的视图模型,使其处理它们引发的
PropertyChanged
事件非常简单。在构造函数中,添加:和此方法:
如果从集合中删除对象,请不要忘记取消注册事件处理程序;否则,直到父视图模型对象被释放之前,子视图模型对象才会被释放。
顺便请注意,通过这种方式实现视图模型,您可以对底层实体模型的更新进行大量控制。例如,您可以在父视图模型中实现一个命令,该命令在单个操作中执行所有更新,而另一个命令则允许用户放弃他们在 UI 中所做的所有更改而不执行更新。所有这些逻辑都很好地与实际的表示层解耦。
Don't create a collection of model objects, and don't implement
IntType
andDescription
properties on your (current) view model. And unless you have some other reason to do so, don't implement property-change notification in your model.Instead, make
IntTypes
a collection ofInterestTypeEntityViewModel
objects.This class wraps
InterestTypeEntity
. It exposesIntType
andDescription
properties that a) wrap the underlyingInterestTypeEntity
properties and b) performs property change notification. If you make its constructor take anInterestTypeEntity
argument, it's easy to populate in your view model:Bind the
ItemsSource
to this collection. (Also, makeCurrentIntType
a property of typeInterestTypeEntityViewModel
and raisePropertyChanged
when it changes.)Edit:
If the owning view model needs to be notified when properties change on the items in its collection, it's pretty simple to make it handle the
PropertyChanged
events they're raising. In your constructor, add:and this method:
Don't forget to unregister the event handler if you remove an object from your collection; otherwise, the child view model objects won't get disposed until the parent one does.
Note, by the way, that by implementing the view models this way, you can exercise a lot of control over your updates to the underlying entity model. For instance, you can implement a command in your parent view model that does all of the updates in a single operation, and another one that lets the user discard all of the changes they've made in the UI without performing an update. And all of this logic is very nicely decoupled from the actual presentation layer.
请此处查看我的回答。它将为您提供一个可观察的集合,告诉您集合何时发生变化,或者集合中的某个项目何时发生变化。
Please see my answer here. It will give you an observable collection that tells you when the collection changes, or when an item within the collection changes.
总体策略:
将 TwoWay 添加到您的绑定中:
然后订阅 ViewModel 中可观察集合的更改事件。当集合发生变化时,将其发送到您的模型/DAL 并保留它。
General strategy:
Add TwoWay to your binding:
And then subscribe to the changed event of the observable collection in your ViewModel. When the collection changes, send it to your model/DAL and persist it.