WPF - 在 CollectionChanged 事件中访问 DependencyObject

WPF - Access DependencyObject inside a CollectionChanged event

我有一个结合了 2 个 DepedenciyProperties 值的用户控件:

int numberPeople and ingredients Lists<>

我希望当这些值中的任何一个更新时重新组合。 我当前的实现使用静态变量来跟踪对象实例 (objectInstance)。我想知道是否有更简洁的方法来做到这一点。

private static DependencyObject objectInstance;

    public int numberPeople
    {
        get { return (int)GetValue(numberPeopleProperty); }
        set { SetValue(numberPeopleProperty, value); }
    }
    public static readonly DependencyProperty numberPeopleProperty =
        DependencyProperty.Register("numberPeople", typeof(int), typeof(ListDisplayer), new PropertyMetadata(0, Combine));


    public ObservableCollection<ListModel> ingredients
    {
        get { return (ObservableCollection<ListModel>)GetValue(ingredientsProperty); }
        set { SetValue(ingredientsProperty, value); }
    }
    public static readonly DependencyProperty ingredientsProperty =
        DependencyProperty.Register("ingredients", typeof(ObservableCollection<ListModel>), typeof(ListDisplayer), new PropertyMetadata(null, AssignCollectionChangedToList));
    private static void AssignCollectionChangedToList(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var instance = d as ListDisplayer;
        if (e.OldValue != null)
        {
            var coll = (INotifyCollectionChanged)e.OldValue;
            coll.CollectionChanged -= ItemsSource_CollectionChanged;
        }

        if (e.NewValue != null)
        {
            instance.ItemsSource = (ObservableCollection<ListModel>)e.NewValue;
            objectInstance = instance;
            instance.ItemsSource.CollectionChanged += ItemsSource_CollectionChanged;
        }
    }

    private static void ItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // MY PROBLEM: when a new item is added in this list trigger again Combine(), is there 
        // another way to trigger the Combine so that it will process the IngredientList and numberPeople attached to the object ? 
        Combine(objectInstance, new DependencyPropertyChangedEventArgs());

    }




    private static void Combine(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // process numberPeople and ingredientList
    }

编辑:ItemsSource_CollectionChanged 事件处理程序的定义中删除 static 关键字,并使用 "instance" 引用将其连接起来:

private static void AssignCollectionChangedToList(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var instance = d as ListDisplayer;
    if (e.OldValue != null)
    {
        var coll = (INotifyCollectionChanged)e.OldValue;
        coll.CollectionChanged -= instance.ItemsSource_CollectionChanged;
    }

    if (e.NewValue != null)
    {
        instance.ingredients = (ObservableCollection<ListModel>)e.NewValue;
        objectInstance = instance;
        instance.ingredients.CollectionChanged += instance.ItemsSource_CollectionChanged;
    }
}

private void ItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    Combine(this, new DependencyPropertyChangedEventArgs());
}

您的依赖属性的 CLR 包装器也没有正确实现。您应该将依赖项 属性 传递给 GetValue 和 SetValue 方法:

public int numberPeople
{
    get { return (int)GetValue(numberPeopleProperty); }
    set { SetValue(numberPeopleProperty, value); }
}
public static readonly DependencyProperty numberPeopleProperty =
    DependencyProperty.Register("numberPeople", typeof(int), typeof(ListDisplayer), new PropertyMetadata(0, Combine));


public ObservableCollection<ListModel> ingredients
{
    get { return (ObservableCollection<ListModel>)GetValue(ingredientsProperty); }
    set { SetValue(ingredientsProperty, value); }
}
public static readonly DependencyProperty ingredientsProperty =
    DependencyProperty.Register("ingredients", typeof(ObservableCollection<ListModel>), typeof(ListDisplayer), new PropertyMetadata(null, AssignCollectionChangedToList));