【发布时间】:2012-03-16 15:09:41
【问题描述】:
有人知道如何自定义ItemsSource吗?
我想做的是为我自己的UserControl创建一个itemsSource,以便它可以被ObservableCollection<>绑定。
另外,我可以知道每当itemsSource中的项目数更新,以便做进一步的程序。
非常感谢。
【问题讨论】:
标签: wpf data-binding itemssource
有人知道如何自定义ItemsSource吗?
我想做的是为我自己的UserControl创建一个itemsSource,以便它可以被ObservableCollection<>绑定。
另外,我可以知道每当itemsSource中的项目数更新,以便做进一步的程序。
非常感谢。
【问题讨论】:
标签: wpf data-binding itemssource
您可能需要在您的控件中执行类似的操作
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(UserControl1), new PropertyMetadata(new PropertyChangedCallback(OnItemsSourcePropertyChanged)));
private static void OnItemsSourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var control = sender as UserControl1;
if (control != null)
control.OnItemsSourceChanged((IEnumerable)e.OldValue, (IEnumerable)e.NewValue);
}
private void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
// Remove handler for oldValue.CollectionChanged
var oldValueINotifyCollectionChanged = oldValue as INotifyCollectionChanged;
if (null != oldValueINotifyCollectionChanged)
{
oldValueINotifyCollectionChanged.CollectionChanged -= new NotifyCollectionChangedEventHandler(newValueINotifyCollectionChanged_CollectionChanged);
}
// Add handler for newValue.CollectionChanged (if possible)
var newValueINotifyCollectionChanged = newValue as INotifyCollectionChanged;
if (null != newValueINotifyCollectionChanged)
{
newValueINotifyCollectionChanged.CollectionChanged += new NotifyCollectionChangedEventHandler(newValueINotifyCollectionChanged_CollectionChanged);
}
}
void newValueINotifyCollectionChanged_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
//Do your stuff here.
}
【讨论】:
newValueINotifyCollectionChanged 始终是null。
在您的 CustomControl 中使用 DependencyProperty ItemsSource,然后绑定到此 DependencyProperty
这是 XAML 代码(识别 ListBox 的 DataContext):
<UserControl
x:Name="MyControl">
<ListBox
DataContext="{Binding ElementName=MyControl}"
ItemsSource="{Binding ItemsSource}">
</ListBox>
</UserControl>
这是代码隐藏:
public partial class MyCustomControl
{
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable),
typeof(ToolboxElementView), new PropertyMetadata(null));
}
这是代码,您可以在其中使用“MyCustomControl”:
<Window>
<local:MyCustomControl
ItemsSource="{Binding MyItemsIWantToBind}">
</local:MyCustomControl>
</Window>
【讨论】:
简化答案。
public IEnumerable ItemsSource
{
get => (IEnumerable)GetValue(ItemsSourceProperty);
set => SetValue(ItemsSourceProperty, value);
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(UserControl1), new PropertyMetadata(null, (s, e) =>
{
if (s is UserControl1 uc)
{
if (e.OldValue is INotifyCollectionChanged oldValueINotifyCollectionChanged)
{
oldValueINotifyCollectionChanged.CollectionChanged -= uc.ItemsSource_CollectionChanged;
}
if (e.NewValue is INotifyCollectionChanged newValueINotifyCollectionChanged)
{
newValueINotifyCollectionChanged.CollectionChanged += uc.ItemsSource_CollectionChanged;
}
}
}));
private void ItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// Logic Here
}
// Do Not Forget To Remove Event On UserControl Unloaded
private void UserControl1_Unloaded(object sender, RoutedEventArgs e)
{
if (ItemsSource is INotifyCollectionChanged incc)
{
incc.CollectionChanged -= ItemsSource_CollectionChanged;
}
}
【讨论】: