我在WPF中有一个可视化控件,它利用了依赖属性。这些属性由字段支持,这些字段是类,有时需要在实际修改包含的类时通知所有绑定,更改属性值。
简单地说:
MSDN说,当首次使用依赖属性时,PropertyChanged附加到DependencyObject。它在Visual Studio 2010中有效。但是,在安装Visual Studio 2012后,它停止工作:即使使用了DP(例如绑定附加到它),PropertyChanged也为null,我无法通知任何人更改。
我仍然使用Visual Studio 2010编译工具包,所以看起来,这是一个破坏框架的问题,它与VS 2012一起更新。
我是否正确使用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);
}
情景:
Binding
Handle
方法(使用IHandle
接口)答案 0 :(得分:1)
首先,这段代码是多余的:
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("DataSource"));
不建议在通常的属性设置器中编写任何其他代码,因为WPF DP系统直接访问DP而不使用setter或getter。
在PropertyChanged
方法中提升OnDataSourceChanged
。
其次,您的控件继承了DependencyObject
允许您添加Dependecny属性的内容
有可能更新改变了以前的行为,并且当绑定到控件的依赖属性时,DP系统现在不会通过ProprtyChanged事件订阅通知,因为不需要它。 DP系统有通知。
这可能是PropertyChanged
为空的原因。
<强>更新强>
我认为像你一样设置CurrentValue会导致细微的错误。通常由于某些内部原因而应更改值时使用SetCurrentValue()
。例如。当用户键入文本时,TextBox
会将Text
属性值设置为SetCurrentValue()
。这样可以保存绑定
但是,如果您尝试以编程方式设置绑定会发生什么?
根据您在评论中所说的内容,您可以尝试:
INotifyPropertyChanged
DependencyObject.InvalidateProperty()