4

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

简单地说:

  • MyDepProp 是 MyClass 类型;
  • MyClass 的内容因控件的内部操作而改变;
  • 我想通知大家,MyDepProp 发生了变化,这样他们就可以反映 MyClass 的变化。

MSDN 说,第一次使用依赖属性时,PropertyChanged 附加到 DependencyObject。它在 Visual Studio 2010 中工作。但是,在安装 Visual Studio 2012 后,它停止工作:即使使用了 DP(例如,绑定已附加到它),PropertyChanged 为空,我无法通知任何人更改。

我仍然使用 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);
}

场景:

  • DataSource使用_Binding
  • 有人调用Handle控件的方法(使用IHandle接口)
  • 处理检查 PropertyChanged 是否不为空,因此不会传播有关 DataSource 中更改的信息。
4

1 回答 1

1

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

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

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

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

更新

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

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

  • 将值设置为 null 然后返回。
  • 实现INotifyPropertyChanged数据源
  • 称呼DependencyObject.InvalidateProperty()
于 2013-03-28T11:24:02.287 回答