自定义UserControl的ItemsSource属性set方法未触发问题排查
问题
我开发了一个自定义UserControl,用于展示所在窗口中的下载聚合数据(下载列表)。包含该控件的窗口基础XAML代码如下:
<Grid> <StackPanel> <ScrollViewer> <ItemsControl ItemsSource="{Binding Downloads}"> . . . </ItemsControl> </ScrollViewer> <local:DownloadStatsControl ItemsSource="{Binding Downloads}"/> </StackPanel> </Grid>
该UserControl的后台代码如下:
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); }
目前ItemsControl可正常绑定Downloads显示数据,但自定义UserControl无法显示数据,且其ItemsSource的set方法未被触发(构造函数已执行)。
注:上述代码与参考的StackOverflow内容不同,在遇到set方法未触发问题时,我参考了ItemControl源码,简化为仅使用IEnumerable类型。
问题原因与解决方法
核心原因
自定义UserControl的构造函数中设置了DataContext = this,替换了控件默认继承的窗口上下文,导致{Binding Downloads}会在DownloadStatsControl自身实例中查找Downloads属性,因找不到该属性导致绑定失效,进而无法触发ItemsSource的set方法。
解决方式
修改XAML中的绑定表达式,通过RelativeSource明确指定绑定上下文为窗口的DataContext,确保正确获取目标数据:
<local:DownloadStatsControl ItemsSource="{Binding DataContext.Downloads, RelativeSource={RelativeSource AncestorType=Window}}"/>
内容的提问来源于stack exchange,提问作者Ron O
相关产品推荐
相关产品推荐

