2013-03-28 51 views
4

我有一個WPF中的可視化控件,它利用了依賴屬性。這些屬性由作爲類的字段支持,並且有時需要通知所有綁定,實際上包含的類被修改時,屬性的值會發生更改。PropertyChanged未連接

簡單地說:

  • MyDepProp是類型的MyClass;
  • 由於控件的內部操作,MyClass的內容發生變化;
  • 我想告訴大家,MyDepProp已更改,以便它們可以反映MyClass中的更改。

MSDN說,當第一次使用依賴項屬性時,PropertyChanged連接到DependencyObject。它在Visual Studio 2010中工作。但是,在安裝Visual Studio 2012之後,它停止工作:即使使用了DP(例如,綁定已附加到它),PropertyChanged爲null,我無法通知任何更改。

我仍然可以使用Visual Studio 2010的編譯器工具包,如此看來,它的破框架,這與2012年VS一起更新

我是否正確使用PropertyChanged事件的問題?還是VS 2012更新的.NET 4.0框架中的錯誤?有沒有人遇到類似的問題?


編輯:將一塊缺陷代碼:

public partial class MyImageControl : INotifyPropertyChanged, 
    IHandle<ImageRefresh> 
{ 
    // *************************** 
    // *** Dependency property *** 
    // *************************** 

    private void OnDataSourceChanged() 
    { 
     // ... 
    } 

    private static void DataSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     if (d is MyImageControl) 
      ((MyImageControl)d).OnDataSourceChanged(); 
    } 

    public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource", 
     typeof(IDataSource), 
     typeof(MyImageControl), 
     new PropertyMetadata(null, DataSourceChanged)); 

    public IDataSource DataSource 
    { 
     get 
     { 
      return (IDataSource)GetValue(DataSourceProperty); 
     } 

     set 
     { 
      SetCurrentValue(DataSourceProperty, value); 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs("DataSource")); 
     } 
    } 

    // *********************************** 
    // *** INotifyPropertyChanged impl *** 
    // *********************************** 

    public event PropertyChangedEventHandler PropertyChanged; 

    // ************************************* 
    // *** Method, which exposes the bug *** 
    // ************************************* 

    public void Handle(ImageRefresh message) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs("BackgroundKind")); 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs("DataSource")); 
    } 
} 

作爲參考,IHandle接口:

public interface IBaseHandle { } 

public interface IHandle<TMessage> : IBaseHandle 
{ 
    void Handle(TMessage message); 
} 

的情形:

  • 的DataSource 結合使用Binding
  • 有人另一個屬性調用控制(使用IHandle接口)
  • 手柄檢查的PropertyChanged是否不爲空的Handle方法,它是,所以沒有關於在數據源的改變信息被傳播。
+1

你能表現出一定的代碼,這一切都在VS2012在我的電腦工作正常... – Peter 2013-03-28 10:25:55

+0

這可能是困難的,它實際上是一個巨大的一部分項目,在許多地方這個機制的作品。這就是我無法輕鬆提供概念代碼的原因。如果我設法這樣做,我會在這裏發佈。這就是爲什麼我問,如果有人也遇到這個問題:) – Spook 2013-03-28 10:32:29

+0

我現在在VS2012使用DP沒有任何問題。確保你有一個datacontext的實例,否則你可能會更新錯誤的。還要確保使用與屬性相同的名稱調用RaisePropertyChanged事件。如果沒有代碼,這些將是我要檢查的第一件事情。 – keyboardP 2013-03-28 10:53:44

回答

1

首先,這個代碼是多餘:

  if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs("DataSource")); 

它不推薦的,因爲WPF DP系統直接訪問的DP不使用設置器或吸氣劑寫在通常的屬性setter任何額外的代碼。 提高PropertyChangedOnDataSourceChanged方法。

其次,你的控制繼承DependencyObject什麼讓你添加Dependecny屬性。
有一個機會,更新改變了以前的行爲和DP系統現在不控制的結合依賴項屬性的時候,因爲沒有必要爲它通過ProprtyChanged事件訂閱通知。 DP系統有通知。
這可能是PropertyChanged爲空的原因。

UPDATE

我認爲設置CurrentValue的,你做的可能會導致微妙的錯誤。由於某些內部原因,應該更改值時通常使用SetCurrentValue()。例如。當用戶鍵入文本時,TextBox將其Text屬性值設置爲SetCurrentValue()。這允許保存綁定。
但是如果您嘗試以編程方式設置綁定會發生什麼?

根據您的意見告訴你可以試試:

  • 將值設置爲空,然後返回。
  • 爲數據源
    實施INotifyPropertyChanged
  • 呼叫DependencyObject.InvalidateProperty()
+0

如果是這樣,我該如何解決這個問題,例如。通知有關DataSource屬性內的更改?如果PropertyChanged沒有以確定性的方式設置,它如何有用?我有一個印象,如果類實現INotifyPropertyChanged,PropertyChanged處理程序保證設置。 – Spook 2013-03-28 12:04:42

+0

請注意,該setter調用'SetCurrentValue',而不是'SetValue'。第一個不傳播有關DP,AFAIK變化的信息。 – Spook 2013-03-28 12:07:35

+0

兩者都傳播,但SetCurrent ...不覆蓋值源。 那麼,爲什麼你需要通知,如果沒有真正的財產變化?如果他們的話DP系統會通知用戶。 – 2013-03-28 12:16:28