Custom ItemsSource property for a UserControl Custom ItemsSource property for a UserControl wpf wpf

Custom ItemsSource property for a UserControl


You may need to do something like this in your control

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.}


Use a DependencyProperty ItemsSource in your CustomControl and then bind to this DependencyProperty

This is the XAML-Code (Recognize the DataContext of the ListBox):

<UserControl    x:Name="MyControl">    <ListBox        DataContext="{Binding ElementName=MyControl}"        ItemsSource="{Binding ItemsSource}">    </ListBox></UserControl>

This is the CodeBehind:

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

This is the Code, where you use your "MyCustomControl":

<Window>    <local:MyCustomControl        ItemsSource="{Binding MyItemsIWantToBind}">    </local:MyCustomControl></Window>


Simplified answer.

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