2013-03-28 50 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