2012-11-27 66 views
1

我有一個自定義控件,它有一個依賴屬性定義在它和我的控制實現INotifyPropertyChanged接口。依賴屬性更新機制

依賴屬性是自定義對象的集合。

方案1

DP的類型是List,無論改變我做的名單,沒有什麼MainUI更新的,因爲我相信WPF不理解添加和列表中刪除的對象。它完全理解新的參考,所以要實現這一點,只要我想更新我的控制列表,我使用

MyProperty = new List();

在這種方法中,我的DP回調每次都會觸發,但eventArgs.NewValue總是保持爲零(它正確地更新了UI上的列表),但是因爲我需要在屬性中編寫一些邏輯,基於e.NewItems.Count更改了回調,這種情況沒有奏效。請告訴我爲什麼e.NewItems不起作用。

方案2

DP是類型的ObservableCollection,因此在視圖模型我的集合屬性針對這我結合我的DP。在這種情況下,我的屬性更改回調根本不會觸發,因爲在第一次初始化屬性後,我再也不使用「new」關鍵字。 UI更新但屬性更改仍未觸發。所以我的財產變化回調邏輯不會被執行。

我應該如何讓他們中的任何一個或他們兩個工作。

+0

這是不對的。 'INotifyPropertyChanged'用於常規(非DependencyObject)POCO對象。您不需要在自定義控件中實現該功能。 –

+0

@HighCore與你同意,我的不好。但刪除並不能解決實際問題。請幫助我。 –

回答

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" }; 
    } 
} 
+0

感謝您的回答,但事情是如果我採用ObservableCollection方式並訂閱CollectionChanged事件,它不僅會在每次更改集合時執行,而且會在集合中的每個單獨項目執行。如果我的集合有100條記錄,這個事件將執行100次,所以這個事件不會是一個運行邏輯的好地方,因爲我不想多次執行這個邏輯。對於屬性中的其他方法更改,它會爲eventargs.new項目賦予null值。 –

+0

不,每次添加或刪除項目時都會引發一次CollectionChanged事件。如果集合中有100個項目,並且再添加一個項目,則不會僅將101次提升爲101.如果DependencyPropertyChangedEventArgs上的NewValue屬性爲空,則表示您執行了錯誤操作。你有沒有試過我寫的代碼? –

0

ObservableCollection繼承自INotifyPropertyChanged和INotifyCollectionChanged。我認爲,如果你想知道什麼時候收集改變你應該使用這個接口:

INotifyCollectionChanged