将正确的NotifyCollectionChangedEventArgs实现到List成员

时间:2015-07-06 13:45:50

标签: c# wpf mvvm

我目前正在创建名为UserControl的{​​{1}}。它是一个带有样式DecoratedComboBox的控件,附近有一些按钮用于实现某些逻辑。

ComboBox有一个自定义DecoratedComboBox(类型为ItemsSource)和其他几个参数,以便在List此字段或该字段中显示该字段ComboBoxItemsSource的{​​{1}}绑定到字段ItemsSource(类型ComboBox),我想同步这两个列表,以便ItemsToShow中的项目反映List中的内容。

目前,我正在研究这段代码中事件ItemsToShow的机制:

ItemsSource

在实现我自己的逻辑之前,我想知道要放入哪些代码行而不是"要放在这里的什么?"评论,以使ItemsSource_CollectionChanged反映 public IList ItemsToShow { get { return (IList)GetValue(ItemsToShowProperty); } set { SetValue(ItemsToShowProperty, value); } } public static readonly DependencyProperty ItemsToShowProperty = DependencyProperty.Register("ItemsSource", typeof(IList), typeof(DecoratedComboBox), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender ) ); public IList ItemsSource { get { return (IList)GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty, value); } } public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IList), typeof(DecoratedComboBox), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(ItemsSourcePropertyChangedCallback) ) ); private static void ItemsSourcePropertyChangedCallback(DependencyObject sender_decorated_combobox, DependencyPropertyChangedEventArgs items_source_changed_args) { DecoratedComboBox decorated_combobox = sender_decorated_combobox as DecoratedComboBox; if decorated_combobox != null) { decorated_combobox.ItemsSourceChanged(items_source_changed_args.OldValue as INotifyCollectionChanged, items_source_changed_args.NewValue as INotifyCollectionChanged); decorated_combobox.BuildList(); } } private void ItemsSourceChanged(INotifyCollectionChanged old_value, INotifyCollectionChanged new_value) { if (old_value != null) { old_value.CollectionChanged -= new NotifyCollectionChangedEventHandler(ItemsSource_CollectionChanged); } if (new_value != null) { new_value.CollectionChanged += new NotifyCollectionChangedEventHandler(ItemsSource_CollectionChanged); } } private void ItemsSource_CollectionChanged(object sender_items_source, NotifyCollectionChangedEventArgs args) { switch (args.Action) { case NotifyCollectionChangedAction.Add: //Insert the items corresponding to args.NewItems at args.NewStartingIndex break; case NotifyCollectionChangedAction.Move: //What to put here? //Should I use only args.OldStartingIndex, args.NewStartingIndex? break; case NotifyCollectionChangedAction.Remove: //Remove all the items corresponding to args.OldItems break; case NotifyCollectionChangedAction.Replace: //What to put here? //Should I use only args.OldItems, args.NewItems, args.NewStartingIndex? break; case NotifyCollectionChangedAction.Reset: BuildList(); break; default: break; } } private void BuildList() { //Fully build (again) ItemsToShow }

我根据具体情况阅读{on this blogItemsToShow哪些成员有用,但我还没有仔细检查,因此审讯标记。

这里的关键思想是,这段(相当长的)代码将成为一种模式,无论我需要在我想要的任何控件上添加ItemsSource,都可以应用。

提前感谢任何线索,如果需要,我可以提供更多信息。

1 个答案:

答案 0 :(得分:0)

您可以倾听这些事件,而无需担心实施全新的ItemsSource财产。相反,您只需使用现有的ItemsSource属性。

如果我是你,我只需在每次更改时致电BuildList。请参阅以下示例:

public class DecoratedComboBox : ComboBox
{
    public IList ItemsToShow
    {
        get { return (IList)GetValue(ItemsToShowProperty); }
        set { SetValue(ItemsToShowProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ItemsToShow.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ItemsToShowProperty =
        DependencyProperty.Register("ItemsToShow", typeof(IList), typeof(DecoratedComboBox), new PropertyMetadata(null));

    static DecoratedComboBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(DecoratedComboBox), new FrameworkPropertyMetadata(typeof(DecoratedComboBox)));
    }

    protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
    {
        base.OnItemsSourceChanged(oldValue, newValue);

        BuildList();
    }

    protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        base.OnItemsChanged(e);

        BuildList();
    }

    private void BuildList()
    {
        //Clear the ItemsToShow List
        ItemsToShow.Clear();

        //TODO: Work out what to put in ItemsToShow
    }
}