依赖属性更新机制

时间:2012-11-27 19:12:14

标签: c# wpf dependency-properties

我有一个自定义控件,它在其中定义了依赖项属性,我的控件实现了INotifyPropertyChanged接口。

依赖属性是自定义对象的集合。

情景1

DP是List类型,无论我在列表中做了什么更改,在MainUI中都没有更新,因为我相信WPF不理解在列表中添加和删除对象。它理解全新的引用,所以为了达到这个目的,每当我想在控件上更新我的列表时我都会使用

MyProperty = new List();

在这种方法中,我的DP回调每次都会触发,但eventArgs.NewValue始终保持为零(它正确地更新了UI上的列表),但是因为我需要在属性更改的回调中编写一些基于e.NewItems.Count的逻辑,在此案件没有用。请告诉我为什么e.NewItems不起作用。

情景2

DP是ObservableCollection类型,所以我在视图模型中的集合属性,我绑定了我的DP。在这种情况下,我的属性更改回调根本不会触发,因为我在第一次初始化属性后再也不会使用“new”关键字。 UI更新但属性更改仍未触发。因此,我在属性更改回调中的逻辑不会被执行。

我应该如何让他们中的任何一个或两个都工作。

2 个答案:

答案 0 :(得分:1)

我会使用ObservableCollection方法,并订阅它的CollectionChanged事件。
这样,无论何时更改集合,您都会收到通知。

但另一种方法也应该有效。将常规列表设置为新实例时,将为依赖项属性触发PropertyChangedCallback,并通过检查DependencyPropertyChangedEventArgs对象获取新值。

XAML:

<StackPanel>
    <Button Content="Add to observablecollection" Click="click1" />
    <Button Content="Set list to new instance" Click="click2" />
</StackPanel>

代码隐藏:

public partial class Window1 : Window
{
    public ObservableCollection<string> Strings { get; set; }

    public List<string> StringsList
    {
        get { return (List<string>)GetValue(StringsListProperty); }
        set { SetValue(StringsListProperty, value); }
    }

    public static readonly DependencyProperty StringsListProperty =
        DependencyProperty.Register("StringsList", typeof(List<string>), typeof(Window), new PropertyMetadata(null, StringsListPropertyChanged));

    public Window1()
    {
        InitializeComponent();

        Strings = new ObservableCollection<string>();
        Strings.CollectionChanged += strings_CollectionChanged;

        StringsList = new List<string> { "Test1", "Test2", "Test3", "Test4" };
    }

    void strings_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        //Fires everytime the observablecollection has an item added/removed etc.
        MessageBox.Show(string.Format("ObservableCollection has changed! Count is now {0}", this.Strings.Count.ToString()));

        if (this.Strings.Count == 10)
            Console.WriteLine("Collection contains 10 strings!!");
    }

    private static void StringsListPropertyChanged(DependencyObject e, DependencyPropertyChangedEventArgs args)
    {
        var newCount = ((List<string>)args.NewValue).Count.ToString();
        MessageBox.Show(string.Format("Dependency property has changed! Count is now {0}", newCount));
    }

    private void click1(object sender, RoutedEventArgs e)
    {
        this.Strings.Add("Test1");
    }

    private void click2(object sender, RoutedEventArgs e)
    {
        this.StringsList = new List<string> { "Newitem1", "Newitem2" };
    }
}

答案 1 :(得分:0)

ObservableCollection继承自INotifyPropertyChanged和INotifyCollectionChanged。我想如果您想知道集合何时更改,您应该使用此界面:

INotifyCollectionChanged