wpf INotifyCollectionChanged redundancy

本文关键字:redundancy INotifyCollectionChanged wpf | 更新日期: 2023-09-27 18:33:25

我编写了一个自定义控件,并且有两个集合依赖项属性SourceA和SourceB。您将在下面的代码中看到依赖项属性"PropertyChanged"方法完全相同,似乎有很多冗余代码。

SourceB_PropertyChanged...
SourceA_PropertyChanged...

我觉得我做得不好。有没有办法在保持收集通知更改的同时删除冗余?

《守则》

using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace NexusEditor
{
    /// <summary>
    /// The main class that implements the network/flow-chart control.
    /// </summary>
    public partial class NexusEditor : Control
    {
        #region Dependency Property/Event Definitions
        private static readonly DependencyPropertyKey ItemsPropertyKey =
            DependencyProperty.RegisterReadOnly("Items", typeof(ObservableCollection<object>), typeof(NexusEditor),
                new FrameworkPropertyMetadata());
        public static readonly DependencyProperty ItemsProperty = ItemsPropertyKey.DependencyProperty;
        public static readonly DependencyProperty SourceAProperty =
            DependencyProperty.Register("SourceA", typeof(IEnumerable), typeof(NexusEditor),
                new FrameworkPropertyMetadata(SourceA_PropertyChanged));
        public static readonly DependencyProperty SourceBProperty =
            DependencyProperty.Register("SourceB", typeof(IEnumerable), typeof(NexusEditor),
                new FrameworkPropertyMetadata(SourceB_PropertyChanged));
        #endregion

        #region Constructors
        public NexusEditor()
        {
            // Create a collection to contain nodes.
            this.Items = new ObservableCollection<object>();
        }
        static NexusEditor()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(NexusEditor), new FrameworkPropertyMetadata(typeof(NexusEditor)));
        }
        #endregion
        #region properties
        public IEnumerable SourceA
        {
            get { return (IEnumerable)GetValue(SourceAProperty); }
            set { SetValue(SourceAProperty, value); }
        }
        public IEnumerable SourceB
        {
            get { return (IEnumerable)GetValue(SourceBProperty); }
            set { SetValue(SourceBProperty, value); }
        }
        /// <summary>
        /// Collection of items
        /// </summary>
        public ObservableCollection<object> Items
        {
            get { return (ObservableCollection<object>)GetValue(ItemsProperty); }
            private set { SetValue(ItemsPropertyKey, value); }
        }
        #endregion
        #region privates
        private static void UpdateItems(NexusEditor editor)
        {
            editor.Items.Clear();
            var sourceB = editor.SourceB as IEnumerable;
            if (sourceB != null)
            {
                foreach (object obj in sourceB)
                {
                    editor.Items.Add(obj);
                }
            }
            var sourceA = editor.SourceA as IEnumerable;
            if (sourceA != null)
            {
                foreach (object obj in sourceA)
                {
                    editor.Items.Add(obj);
                }
            }
        }
        /// <summary>
        /// Event raised when a new collection has been assigned to the SourceB property.
        /// </summary>
        private static void SourceB_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NexusEditor c = (NexusEditor)d;
            if (e.OldValue != null)
            {
                var notifyCollectionChanged = e.OldValue as INotifyCollectionChanged;
                if (notifyCollectionChanged != null)
                {
                    notifyCollectionChanged.CollectionChanged -= new NotifyCollectionChangedEventHandler(c.SourceB_CollectionChanged);
                }
            }
            if (e.NewValue != null)
            {
                var notifyCollectionChanged = e.NewValue as INotifyCollectionChanged;
                if (notifyCollectionChanged != null)
                {
                    notifyCollectionChanged.CollectionChanged += new NotifyCollectionChangedEventHandler(c.SourceB_CollectionChanged);
                }
            }
            UpdateItems(c);
        }
        /// <summary>
        /// Event raised when a node has been added to or removed from the collection assigned to 'NodesSource'.
        /// </summary>
        private void SourceB_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            UpdateItems(this);
        }

        /// <summary>
        /// Event raised when a new collection has been assigned to the SourceB property.
        /// </summary>
        private static void SourceA_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            NexusEditor c = (NexusEditor)d;
            if (e.OldValue != null)
            {
                var notifyCollectionChanged = e.OldValue as INotifyCollectionChanged;
                if (notifyCollectionChanged != null)
                {
                    notifyCollectionChanged.CollectionChanged -= new NotifyCollectionChangedEventHandler(c.SourceA_CollectionChanged);
                }
            }
            if (e.NewValue != null)
            {
                var notifyCollectionChanged = e.NewValue as INotifyCollectionChanged;
                if (notifyCollectionChanged != null)
                {
                    notifyCollectionChanged.CollectionChanged += new NotifyCollectionChangedEventHandler(c.SourceA_CollectionChanged);
                }
            }
            UpdateItems(c);
        }
        /// <summary>
        /// Event raised when a node has been added to or removed from the collection assigned to 'NodesSource'.
        /// </summary>
        private void SourceA_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            UpdateItems(this);
        }
        #endregion
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
        }
    }
}

wpf INotifyCollectionChanged redundancy

例如,

为什么不创建一个名为Source_PropertyChangedPropertyChanged处理程序方法并将其用于两个依赖项属性?

如果它们完全相同,你可以这样做。

public static readonly DependencyProperty SourceAProperty =
    DependencyProperty.Register("SourceA", typeof(IEnumerable), typeof(NexusEditor), 
    new FrameworkPropertyMetadata(Source_PropertyChanged));
public static readonly DependencyProperty SourceBProperty =
    DependencyProperty.Register("SourceB", typeof(IEnumerable), typeof(NexusEditor),
    new FrameworkPropertyMetadata(Source_PropertyChanged));

处理程序:

private static void Source_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    NexusEditor c = (NexusEditor)d;
    if (e.OldValue != null)
    {
        var notifyCollectionChanged = e.OldValue as INotifyCollectionChanged;
        if (notifyCollectionChanged != null)
        {
            notifyCollectionChanged.CollectionChanged -= new NotifyCollectionChangedEventHandler(c.Source_CollectionChanged);
        }
    }
    if (e.NewValue != null)
    {
        var notifyCollectionChanged = e.NewValue as INotifyCollectionChanged;
        if (notifyCollectionChanged != null)
        {
            notifyCollectionChanged.CollectionChanged += new NotifyCollectionChangedEventHandler(c.Source_CollectionChanged);
        }
    }
    UpdateItems(c);
}

对于已更改的集合:

private void Source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    UpdateItems(this);
}