如何通知家长';s视图模型的子对象';的视图模型属性已更改
本文关键字:视图 模型 对象 属性 何通知 通知 | 更新日期: 2023-09-27 18:24:04
我有一个窗口,比如
- 相册(父窗口)
- 相册属性(子项)
在"相册"窗口中,我有相册列表、"新建相册"按钮、"保存"按钮和"属性"按钮的组合框。
我只想在相册处于编辑模式时启用保存按钮。当我在相簿中添加新照片时,PhotoAlbum将进入编辑模式,或者如果我通过单击属性按钮更改属性,则会进入编辑模式
我有房产,
PhotoAlbumVM 中的IsPhotoAlbumUpdated
PhotoAlbumPropertyVM 中的IsPhotoAlbumPropertyUpdated
IsSaveEnabled
{
get return this.IsPhotoAlbumUpdated || this.SelectedAlbum.IsPhotoAlbumPropertyUpdated;
}
in PhotoAlbumVM
<Button Name="BtnSave" Command="{Binding Save}"
ToolTip="{x:Static resx:Resource.ToolTipSave}" Focusable="True"
IsEnabled="{Binding IsSaveEnabled}">
现在,当this.SelectedAlbum.IsPhotoAlbumPropertyUpdated
发生更改时,我的父视图模型(即PhotoAlbumVM)将如何知道这一点?
我本来想用棱镜事件,但为了做这么小的事情,我不想用棱镜活动。
请给我另一种逻辑。
您需要侦听子项的OnPropertyChanged
事件。每次更改SelectedAlbum
时,在set
中,使用album.PropertyChanged -= MyPropertyChanged
将处理程序从旧相册中删除,除非它为null,并使用value.PropertyChanged += MyPropertyChanged
将处理程序分配给新值。在MyPropertyChanged
中,强制更新IsSaveEnabled
的新值。
您可以在CollectionChanged上为集合项订阅PropertyChanged
事件。如果您的UI正确绑定到ObservableCollection中的项,则不需要告诉UI在集合中的项的属性发生更改时进行更新。如果必须做出一致的行为,您可以收集特定对象,也可以使用下面的实现跨应用程序进行收集。
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Collections;
namespace VJCollections
{
/// <summary>
/// This class adds the ability to refresh the list when any property of
/// the objects changes in the list which implements the INotifyPropertyChanged.
/// </summary>
/// <typeparam name="T">
public class ItemsChangeObservableCollection<T> :
ObservableCollection<T> where T : INotifyPropertyChanged
{
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
RegisterPropertyChanged(e.NewItems);
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
UnRegisterPropertyChanged(e.OldItems);
}
else if (e.Action == NotifyCollectionChangedAction.Replace)
{
UnRegisterPropertyChanged(e.OldItems);
RegisterPropertyChanged(e.NewItems);
}
base.OnCollectionChanged(e);
}
protected override void ClearItems()
{
UnRegisterPropertyChanged(this);
base.ClearItems();
}
private void RegisterPropertyChanged(IList items)
{
foreach (INotifyPropertyChanged item in items)
{
if (item != null)
{
item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
private void UnRegisterPropertyChanged(IList items)
{
foreach (INotifyPropertyChanged item in items)
{
if (item != null)
{
item.PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
}