BindingList 元素属性更改时缺少 PropertyChanged 事件
我有一个类 ViewModel
,它具有 BindingList
类型的属性 MyList
。
ViewModel
实现 INotifyPropertyChanged
。
Foo 具有属性 FooProp
。
Foo
实现 INotifyPropertyChanged
ViewModel 具有此属性:
public bool IsButtonEnabled
{
get
{
return MyList.Any(x=> x.FooProp!=null);
}
}
我有一个带有按钮的视图。按钮的 Enabled 属性绑定到 IsButtonEnabled
。
但是,当 MyList
的元素设置了 FooProp
时,该按钮不会启用。我注意到 ViewModel
不会在此处触发 PropertyChanged
事件。为什么不呢?我应该如何让视图模型注意到它的 IsButtonEnabled 属性实际上已更改?
I have a class ViewModel
that has a property MyList
of type BindingList<Foo>
.
ViewModel
implements INotifyPropertyChanged
.
Foo has the property FooProp
.
Foo
implements INotifyPropertyChanged
ViewModel has this property:
public bool IsButtonEnabled
{
get
{
return MyList.Any(x=> x.FooProp!=null);
}
}
I have a view with a button. The Enabled property of the button is bound to IsButtonEnabled
.
But the button doesn't get enabled when an element of MyList
has it's FooProp
set. I've noticed that ViewModel
doesn't fire a PropertyChanged
event here. Why not? And how should I go about for the view model to notice that it's IsButtonEnabled
property actually has changed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
ViewModel 不会在此处触发任何 PropertyChanged,因为 ViewModel 的属性未更改。已更改的实际属性 FooProp 是 Foo 类的属性,而不是 ViewModel。
为了根据
IsButtonEnabled
功能启用/禁用按钮,您必须跟踪 MyList 的所有元素并查看是否进行了任何更改。因此,以下内容应该有效:请注意,在这种情况下,您需要使用 ViewModel.AddItem() 才能将项目添加到 MyList(您可以使用 MyList.Add(),但它不会触发正确的通知)。
此外,上面的代码并不是最好的方法 - 它只是说明您的案例应该如何工作。在您了解之后,您可能会替换 List<>到 ObservableCollection<>能够自动跟踪/处理列表中的项目。
ViewModel will not fire any PropertyChanged here because ViewModel's properties are not changed. The actual property that was changed
FooProp
which is a property of class Foo, not ViewModel.In order to enable/disable the button based on the
IsButtonEnabled
functionality you will have to track all the elements of MyList and see if any changes are done. So, the following should work:Note that in this case you need to use ViewModel.AddItem() in order to add an item to MyList (you can use MyList.Add(), but it will not fire the correct notifications then).
Also the code above is not the best way to do it - it is just an illustration of how your case should work. After you understand that you are probably going to replace the List<> to ObservableCollection<> to be able to track/handle items in your list automatically.
编辑:没有注意到这是一个 getter 而不是 setter。重点还是一样的。简单地实现 INotifyPropertyChanged 接口并不会自动添加您需要的所有内容。您需要创建触发事件的方法(如下)。然后您需要在所有属性的 SETTER 中调用该方法。
您不应该自己触发 PropertyChanged 事件吗?
INotifyPropertyChanged
接口仅为您创建事件。您需要自己从 ViewModel 触发该事件。如果您尚未创建该方法,则此方法通常可以工作。当 ViewModel 的属性发生更改时,您将显式调用此方法。
EDITED: Didn't notice that this was a getter and not a setter. The point is still the same. Simply implementing the
INotifyPropertyChanged
interface doesn't automatically add everything you need. You need to create the method(below) that fires the event. Then you need to call that method in the SETTER of all of your properties.Shouldn't you fire the PropertyChanged event yourself?
The
INotifyPropertyChanged
interface only creates the event for you. You need to fire the event from the ViewModel yourself.If you haven't already created the method, this one normally works. You would call this method explicitly when a property of the ViewModel changes.