wpf INotifyCollectionChanged redundancy

时间:2016-02-06 12:51:52

标签: c# wpf

我已经编写了自定义控件,并且我有两个集合依赖项属性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();

        }
    }
}

1 个答案:

答案 0 :(得分:1)

为什么不创建一个名为PropertyChanged的{​​{1}}处理程序方法,并将其用于两个依赖项属性?

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

Source_PropertyChanged

处理程序:

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);
}