我目前正在创建一个名为UserControl
的DecoratedComboBox
。这是一个带有样式ComboBox
的控件,附近带有一些用于实现某些逻辑的按钮。DecoratedComboBox
具有自定义的ItemsSource
(类型为List
)和其他几个参数,以便在ComboBox
中显示此字段或ItemsSource
中各项的该字段。 ItemsSource
的ComboBox
绑定(bind)到字段ItemsToShow
(类型为List
),并且我想同步两个列表,以便ItemsToShow
中的项目反射(reflect)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
}
在实现自己的逻辑之前,我想知道要放置哪些代码行,而不是“此处放置什么?”。为了使
ItemsToShow
反射(reflect)ItemsSource
的注释?我已经阅读了(on this blog)关于
args
的哪些成员(取决于情况)的信息,但是我还没有仔细检查过,因此没有询问。这里的关键思想是,这段(相当长的)代码将成为一种模式,适用于我需要在我正在构思的任何控件上添加
ItemsSource
的地方。在此先感谢您提供任何线索,如有需要,我可以提供更多信息。
最佳答案
您可以监听这些事件,而不必担心实现全新的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
}
}
关于c# - 将正确的NotifyCollectionChangedEventArgs实现到List成员,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31247509/