gpt4 book ai didi

c# - PropertyChanged 未附加

转载 作者:行者123 更新时间:2023-11-30 12:47:51 46 4
gpt4 key购买 nike

我在 WPF 中有一个可视化控件,它利用了依赖属性。这些属性由字段支持,这些字段是类,有时需要通知所有绑定(bind),当实际包含的类被修改时,属性值已更改。

简单地说:

  • MyDepProp 是 MyClass 类型;
  • MyClass的内容因控件的内部操作而改变;
  • 我想通知大家,MyDepProp 已更改,以便他们可以反射(reflect) MyClass 中的更改。

MSDN 说,当第一次使用依赖属性时,PropertyChanged 附加到 DependencyObject。它在 Visual Studio 2010 中工作。但是,在安装 Visual Studio 2012 之后,它停止工作:即使使用了 DP(例如绑定(bind)附加到它),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 接口(interface):

public interface IBaseHandle { }

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

场景:

  • DataSource 使用 Binding
  • 绑定(bind)到另一个属性
  • 有人调用控件的Handle方法(使用IHandle接口(interface))
  • 处理检查,PropertyChanged 是否不为 null 而确实为 null,因此不会传播有关 DataSource 中更改的信息。

最佳答案

首先,这段代码是多余的:

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

不建议在通常的属性 setter 中编写任何额外的代码,因为 WPF DP 系统直接访问 DP,而无需使用 setter 或 getter。在 OnDataSourceChanged 方法中引发 PropertyChanged

其次,您的控件继承了DependencyObject,它允许您添加 Dependecny 属性。
更新有可能改变了以前的行为,并且 DP 系统现在在绑定(bind)到控件的依赖属性时不会通过 ProprtyChanged 事件订阅通知,因为不需要它。 DP系统有通知。
这可能是 PropertyChanged 为 null 的原因。

更新

我认为按照您的方式设置 CurrentValue 会导致细微的错误。通常 SetCurrentValue() 用于由于某些内部原因应更改值时。例如。 TextBox 在用户键入文本时使用 SetCurrentValue() 设置其 Text 属性值。这允许保存绑定(bind)。
但是,如果您尝试以编程方式设置绑定(bind),会发生什么情况?

根据您在评论中所说的,您可以尝试:

  • 将值设置为 null,然后返回。
  • 为数据源实现 INotifyPropertyChanged
  • 调用DependencyObject.InvalidateProperty()

关于c# - PropertyChanged 未附加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15678967/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com