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

时间:2010-06-05 22:27:18

标签: 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));
}

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

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

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

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

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

然而,我可以看到一个肮脏的解决方案 -

  1. 在Window类中,我必须订阅绑定到TabControl的集合的CollectionChanged事件。
  2. 每当项目被添加到该集合时,使用ItemContainerGenerator获取I假设TabItem的副本并使用它来查找“复杂控制”的正确副本
  3. Regiter项目处理程序到'复杂控件'事件来完成工作
  4. 这是错误的,因为:

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

2 个答案:

答案 0 :(得分:6)

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

您不需要将您的属性作为依赖项属性,只需要您的类实现INotifyPropertyChanged并在对象状态以会影响值的方式更改时调用OnPropertyChanged你想暴露给绑定。

因此,假设您有一个要绑定的属性SumSum属性simple将两个其他属性(或字段或其他)添加在一起。当发生影响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");
    }
}

答案 1 :(得分:0)

在我看来,你已经背负了一个WPF用户控件,这个控件是由不打算用于数据绑定的人构建的。我认为这是出于以下两个原因之一:a)有一些逻辑上的原因是你不能绑定到这个属性,或者b)这个控件的原作者不知道他在做什么。您没有提供足够的信息让我知道这两个条件中哪一个是你真正合作的条件。

但一般而言,您无法公开绑定的计算属性的原因是计算属性通常没有setter。设置一个计算其值的属性是没有意义的。

如果还有其他属性需要在更改时更新其值,那么正确的方法(或者至少是依赖属性设计的一个辅助)是在依赖属性的回调函数中处理这些更新,这是回调函数的用途。