Reference: Custom ItemsSource property for a UserControl
I have a custom UserControl
to display a set of aggregate data for the window it’s contained in (a list of downloads). The basics of the UserControl
are
<code><Grid>
<StackPanel>
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Downloads}">
.
.
.
</ItemsControl>
</ScrollViewer>
<local:DownloadStatsControl ItemsSource="{Binding Downloads}"/>
</StackPanel>
</Grid>
</code>
<code><Grid>
<StackPanel>
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Downloads}">
.
.
.
</ItemsControl>
</ScrollViewer>
<local:DownloadStatsControl ItemsSource="{Binding Downloads}"/>
</StackPanel>
</Grid>
</code>
<Grid>
<StackPanel>
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Downloads}">
.
.
.
</ItemsControl>
</ScrollViewer>
<local:DownloadStatsControl ItemsSource="{Binding Downloads}"/>
</StackPanel>
</Grid>
The behind code for the UserControl
contains
<code> public DownloadStatsControl()
{
InitializeComponent();
DataContext = this;
}
[Bindable(true)]
public IEnumerable ItemsSource
{
get => (IEnumerable)GetValue(ItemsSourceProperty);
set
{
if (value == null)
ClearValue(ItemsSourceProperty);
else
SetValue(ItemsSourceProperty, value);
}
}
// Using a DependencyProperty as the backing store for ItemsSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemsSourceProperty
= DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(DownloadStatsControl),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnItemsSourceChanged)));
private static void OnItemsSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var control = sender as DownloadStatsControl;
control?.OnItemsSourceChanged((FixedSizeQueue<DownloadState>)e.OldValue, (FixedSizeQueue<DownloadState>)e.NewValue);
}
</code>
<code> public DownloadStatsControl()
{
InitializeComponent();
DataContext = this;
}
[Bindable(true)]
public IEnumerable ItemsSource
{
get => (IEnumerable)GetValue(ItemsSourceProperty);
set
{
if (value == null)
ClearValue(ItemsSourceProperty);
else
SetValue(ItemsSourceProperty, value);
}
}
// Using a DependencyProperty as the backing store for ItemsSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemsSourceProperty
= DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(DownloadStatsControl),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnItemsSourceChanged)));
private static void OnItemsSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var control = sender as DownloadStatsControl;
control?.OnItemsSourceChanged((FixedSizeQueue<DownloadState>)e.OldValue, (FixedSizeQueue<DownloadState>)e.NewValue);
}
</code>
public DownloadStatsControl()
{
InitializeComponent();
DataContext = this;
}
[Bindable(true)]
public IEnumerable ItemsSource
{
get => (IEnumerable)GetValue(ItemsSourceProperty);
set
{
if (value == null)
ClearValue(ItemsSourceProperty);
else
SetValue(ItemsSourceProperty, value);
}
}
// Using a DependencyProperty as the backing store for ItemsSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemsSourceProperty
= DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(DownloadStatsControl),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnItemsSourceChanged)));
private static void OnItemsSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var control = sender as DownloadStatsControl;
control?.OnItemsSourceChanged((FixedSizeQueue<DownloadState>)e.OldValue, (FixedSizeQueue<DownloadState>)e.NewValue);
}
My challenge is the set for ItemsSource
isn’t called. The constructor is called.
Of note: The code above is different from the referenced SO. When I wasn’t getting the set called, I referred to the ItemControl
source and pulled it back to basics (i.e., just use IEnumerable
).
What am I missing here?