如何通知家长';s视图模型的子对象';的视图模型属性已更改

本文关键字:视图 模型 对象 属性 何通知 通知 | 更新日期: 2023-09-27 18:24:04

我有一个窗口,比如

  1. 相册(父窗口)
  2. 相册属性(子项)

在"相册"窗口中,我有相册列表、"新建相册"按钮、"保存"按钮和"属性"按钮的组合框。

我只想在相册处于编辑模式时启用保存按钮。当我在相簿中添加新照片时,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)将如何知道这一点?

我本来想用棱镜事件,但为了做这么小的事情,我不想用棱镜活动。

请给我另一种逻辑。

如何通知家长';s视图模型的子对象';的视图模型属性已更改

您需要侦听子项的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));
        }
    }
}