Tipp der Woche
28.04.2022, 14:07 Uhr
WPF: ItemsSource für Control implementieren
Über die Eigenschaft ItemsSource bindet man Datensammlungen an Controls wie DataGrid oder ListView. Wie implementiert man aber diese Eigenschaft in einem eigenen Control?
ItemsSource sorgt dafür, dass sich bei einer Veränderung in der angebundenen Collection das Control neu zeichnet. Was aber, wenn das Control, das man selbst bauen will, auch über so einen Mechanismus verfügen soll?
Es gibt Empfehlungen, bei so einem Ansinnen das ItemsControl zu verwenden. Das kennt bereits die Eigenschaft ItemsSource. Wer das aber nicht machen, sondern beispielsweise ein Grid erweitern will, der kann auf den Quellcode von Gaurav Werma zurückgreifen. Unter https://gaurawerma.wordpress.com/2012/02/28/handling-inotifycollectionchanged-event/
findet sich:
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 = newValue 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***
}
Bei //***Do your stuff here*** kommt dann die Aktualisierung des Controls hinein. Hier können beispielsweise alle Kinder des Grids gelöscht und neu angelegt werden.