WPF公开绑定的计算属性(作为DependencyProperty)

kub*_*003 5 wpf dependency-properties

我有一个复杂的WPF控件,由于某些原因(即性能)没有使用依赖属性而是简单的C#属性(至少在顶级,它们作为属性公开).

目标是使绑定到一些顶级属性成为可能 - >我想我应该将它们声明为DP.(对吗?还是有其他方法来实现这一点?)

我开始在MSDN上阅读DependencyProperties和DependencyObjects并找到一个例子:

public class MyStateControl : ButtonBase
{
  public MyStateControl() : base() { }
  public Boolean State
  {
    get { return (Boolean)this.GetValue(StateProperty); }
    set { this.SetValue(StateProperty, value); } 
  }
  public static readonly DependencyProperty StateProperty = DependencyProperty.Register(
    "State", typeof(Boolean), typeof(MyStateControl),new PropertyMetadata(false));
}
Run Code Online (Sandbox Code Playgroud)

如果我是对的 - 这段代码强制要由DependencyProperty备份属性,它将它限制为一个带存储的简单属性(从功能的角度来看,不是技术上的),而不是每次getter都能计算属性值调用并在每次调用setter时设置其他属性/字段.

我该怎么办?有什么方法可以让这两个世界在某个时刻相遇吗?

//编辑我想我必须告诉你更多关于我想做什么以及我的局限性.所以:

我有TabControl绑定到ViewModel(我正在使用MVVM模式)对象的集合.每个选项卡都是该集合的一个对象的编辑器.对象可以是不同的类型,因此我有多个定义,每个定义具有不同的DataType属性.现在,我有一个复杂的WPF控件,我想将其用作其中一个DataTemplates的一部分.如果我使用通常的TextBox,我可以简单地绑定到它的Text属性,但我不能对该自定义控件的Text属性执行相同的操作,因为它的Text属性不是依赖属性.在这种情况下,我有:

  • 没有直接访问控件本身或其事件
  • 我可以用来做这种事情的文件背后没有代码

但我能看到一个肮脏的解决方案 -

  1. 在Window类中,我必须订阅绑定到TabControl的集合的CollectionChanged事件.
  2. 每当将项目添加到该集合时,使用ItemContainerGenerator获取I假设TabItem的副本并使用它来查找"复杂控制"的正确副本
  3. Regiter项目处理程序将"复杂控件"事件用于完成工作

这是错误的,因为:

  • 这也是MVVM - 我必须使用tab控件来完成工作而不是在ViewModel类中执行它
  • 这会以不受欢迎的方式结合视图和视图模型

Phi*_*ler 6

我认为你正在混合依赖属性并INotifyPropertyChanged在你的类上实现.

您不需要将属性作为依赖项属性,只要对象的状态以会影响要向绑定公开的值的方式更改,您只需要实现INotifyPropertyChanged和调用类OnPropertyChanged.

因此,假设您有一个Sum要绑定的属性.该Sum属性简单地将两个其他属性(或字段或其他)一起添加.当任何影响Sum计算的事情发生时,您希望通知该Sum值已更改,因此任何绑定的控件Sum都会更新.

public int Sum => Value1 + Value2;

public int Value1
{
    set
    {
        // changing  this affects "Sum", so I need to notify that the binding should update
        _value1 = value;
        OnPropertyChanged("Sum");
    }
}

public int Value2
{
    set
    {
        // changing this affects "Sum", so I need to notify that the binding should update
        _value2 = value;
        OnPropertyChanged("Sum");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 是否有最佳实践建议将INotifyPropertyChanged和DependencyProperties混合在同一个类中? (5认同)

Rob*_*ney 0

在我看来,您所使用的 WPF 用户控件是由不打算将其与数据绑定一起使用的人构建的。我认为这是出于以下两个原因之一:a)存在一些逻辑原因,您不应该能够绑定到此属性,或者b)此控件的原始作者不知道他在做什么。您没有提供足够的信息让我知道您真正在这两种条件下工作的哪一种。

但一般来说,无法公开计算属性进行绑定的原因是计算属性通常没有 setter。设置一个已计算值的属性是没有意义的。

如果还有其他属性的值需要在该属性更改时更新,则正确的方法(或者至少是与依赖属性的设计一致的方法)是在依赖属性的回调函数中处理这些更新,这就是一种回调函数是为了。