可观察集合
我有一个绑定到 ObservableCollection
类型列表的 WPF 对话框。在对话框中,我希望仅在对 ObservableCollection
列表进行更改时启用“确定”按钮 - 包括从列表中添加/删除项目以及修改列表中的各个项目列表。
要从列表中添加/删除项目,这很容易 - 我为 CollectionChanged
事件实现了一个处理程序。
我不知道当修改单个项目时该怎么做。比如说,MyEntity.Name="New Value",MyEntity 类需要实现什么接口才能使其“可观察”?
I have a WPF dialog that is bound to a list of ObservableCollection<MyEntity>
type. In the dialog, I want the "OK" button to be enabled only if changes are made to the ObservableCollection<MyEntity>
list - that includes adding/removing items from the list and modifying the individual items in the list.
For adding/removing items from the list, it is easy - I implemented a handler for the CollectionChanged
event.
What I don't know how to do is when an individual item is modified. Say, MyEntity.Name="New Value", what interface does MyEntity class need to implement to make it 'observable'?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
MyEntity
需要实现 INotifyPropertyChanged,然后当属性发生更改时,您将触发 PropertyChanged 事件。像这样:解决这个问题的两种方法是:
在对象内部有一个事件侦听器,然后每当属性更改时它就会设置 IsDirty 标志。然后将
OK
按钮绑定到一个命令(查看ICommand接口的用法),并在该命令的CanExecute方法中检查ObservableCollection中的任何对象是否已设置为dirty。此检查可以使用简单的 LINQ 语句来完成:myCollection.Any(x => x.IsDirty == true)
此方法更加笨重且有异味......有一个外部对象侦听更改(通过订阅每个对象上的 PropertyChanged 事件),然后该外部侦听器可以启用“确定”按钮(通过数据绑定或直接设置)。
MyEntity
needs to implement INotifyPropertyChanged, then when a property change occurs you fire the PropertyChanged event. Like this:Two ways to approach this are:
have an event listener internal to the object which then sets an IsDirty flag whenever a property changes. Then
OK
button is bound to a command (check out the usage of the ICommand interface), and in the CanExecute method of the command you check if any of the objects in the ObservableCollection have been set to dirty. This check can be done with a simple LINQ statement:myCollection.Any(x => x.IsDirty == true)
this method is more clunky and smelly.... have an external object listening for changes (by subscribing to the PropertyChanged event on each object), and that external listener can then enable the OK button (via databinding or by setting it directly).
我喜欢 slugster 提供的答案,这是基于 slugster 答案的替代方案。
如果使用 DelegateCommnd 绑定到“确定”按钮,则可以为 CollectionChanged 和 PropertyChanged 添加事件处理程序,以更改简单的布尔标志来控制“确定”按钮的状态。
这是 MyEntity 的一个版本(类似于 slugster 提供的版本):
在此示例中,只有 Name 属性触发事件...
I like the answer provided by slugster, here is an alternative building on slugster's answer.
If you bind to your OK button using DelegateCommnd you can add event handlers for CollectionChanged and PropertyChanged to change a simple boolean flag to control the state of the OK button.
Here is a version MyEntity (similar to the one provided by slugster):
Only the Name property fires an event in this example...
您应该实现
INotifyPropertyChanged
。你可以通过以下方式做到这一点(如您所见,此实现是完全线程安全的)
按照我上面描述的实现,您可以通过两种方式通知您的更改
1) 第一种方式
2) 第二种方式
You should implement
INotifyPropertyChanged
. You could do it by the following way(as you can see, this implementation is fully thread safe)
Following the implementation I described above, you can notify about your changes by two ways
1) The first way
2) And the second way
另一种解决方案可能是自定义可观察集合,它需要项目实现 INotifyPropertyChanged。用户必须将处理程序附加到
OnItemPropertyChanged
事件,只要集合中项目的属性发生更改,就会调用该处理程序。配置处理程序如下:
...
Another solution could be a custom observable collection that requires items to implement
INotifyPropertyChanged
. The user must attach a handler to theOnItemPropertyChanged
event, which will be called whenever the property of an item in the collection is changed.Configure the handler as follows:
...