绑定到另一个 ObservableCollection 的 ObservableCollection 不会触发 CollectionChanged

ObservableCollection binded to another ObservableCollection does not fire CollectionChanged

提问人:Notrum666 提问时间:11/17/2023 最后编辑:Notrum666 更新时间:11/17/2023 访问量:54

问:

我有 ControlA 托管 ControlB,它们都有 ObservableCollection 类型的 DependencyProperty,嵌套控件的 (ControlB) 属性绑定到父 (ControlA) 属性,如果将某些内容添加到 ControlA 的集合中 - 它的 CollectionChanged 被触发,但 ControlB 的没有,我怎样才能让它触发?下面是最小的示例: MainWindow.xaml:

<Window x:Class="WpfTest.MainWindow"
        ... >
    <Grid>
        <local:ControlA>
            <Rectangle/>
        </local:ControlA>
    </Grid>
</Window>

ControlA.xaml:

<UserControl x:Class="WpfTest.ControlA"
             ... 
             x:Name="ThisControlA">
    <Grid>
        <local:ControlB Items="{Binding Items, ElementName=ThisControlA}"/>
    </Grid>
</UserControl>

ControlA.xaml.cs:

[ContentProperty("Items")]
public partial class ControlA : UserControl
{
    public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ObservableCollection<FrameworkElement>), typeof(ControlA));
    public ObservableCollection<FrameworkElement> Items
    {
        get { return (ObservableCollection<FrameworkElement>)GetValue(ItemsProperty); }
        set
        {
            if (Items != null)
                Items.CollectionChanged -= DockableHost_CollectionChanged;

            SetValue(ItemsProperty, value);

            Items.CollectionChanged += DockableHost_CollectionChanged;
        }
    }
    public ControlA()
    {
        InitializeComponent();

        DataContext = this;

        Items = new ObservableCollection<FrameworkElement>();
    }
    private void DockableHost_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        Debug.WriteLine("This is firing.");
    }
}

ControlB.xaml:

<UserControl x:Class="WpfTest.ControlB"
             ... >
    <Grid>
            
    </Grid>
</UserControl>

ControlB.xaml.cs:

[ContentProperty("Items")]
public partial class ControlB : UserControl
{
    public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ObservableCollection<FrameworkElement>), typeof(ControlB));
    public ObservableCollection<FrameworkElement> Items
    {
        get { return (ObservableCollection<FrameworkElement>)GetValue(ItemsProperty); }
        set
        {
            if (Items != null)
                Items.CollectionChanged -= DockableHost_CollectionChanged;

            SetValue(ItemsProperty, value);

            Items.CollectionChanged += DockableHost_CollectionChanged;
        }
    }

    public ControlB()
    {
        InitializeComponent();

        DataContext = this;

        Items = new ObservableCollection<FrameworkElement>();
    }
    private void DockableHost_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        Debug.WriteLine("This is not firing.");
    }
}

任何想法如何使 CollectionChanged 在 ControlB 中火?

C# WPF XAML ObservableCollection 依赖项属性

评论

3赞 emoacht 11/17/2023
尝试在 DependencyProperty 的 CLR 属性设置器处捕获新值是个坏主意,因为来自 xaml 绑定的新值不会通过它。请改用 DependencyProperty.Register 的 propertyChangedCallback 参数。
0赞 Notrum666 11/17/2023
是的,它奏效了,谢谢,你能把它作为答案发布,以便我可以接受它吗?其他人的一些代码示例也很棒

答: 暂无答案