WPF暴露一个计算属性以供绑定(作为DependencyProperty)

6

我有一个复杂的 WPF 控件,由于某些原因(例如性能),它没有使用依赖属性,而是简单的 C# 属性(至少在顶层这些被公开为属性)。

目标是使绑定到其中一些顶层属性成为可能 -> 我猜我应该将它们声明为 DPs。(对吗?还是有其他方法可以实现此目标?)

我开始阅读 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属性不是依赖属性。 在这种情况下,我有:
没有直接访问控件本身或其事件 没有可以用来做这种事情的代码后台文件
然而,我可以看到一个肮脏的解决方案-
在Window类中,我将需要订阅绑定到TabControl的集合的CollectionChanged事件。 每当向该集合添加一个项目时,使用ItemContainerGenerator获取I suppose TabItem的副本,并使用它找到正确的'complex control'的副本 注册items处理程序以执行任务
这是错误的,因为:
这是反对MVVM的-我必须使用选项卡控件来完成工作,而不是在ViewModel类中完成工作 这种方式会以不想要的方式耦合视图和视图模型
2个回答

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");
    }
}

谢谢回复。我在上面的帖子中写了更多关于我的情况的信息(已编辑)。 - kubal5003
5
在同一个类中混合使用INotifyPropertyChanged和DependencyProperties,是否有最佳实践建议? - BrainSlugs83

0

我觉得你被一个不打算使用数据绑定的WPF用户控件所困扰。我猜这有两个原因之一:a)有一些逻辑上的原因,你不能绑定到这个属性,或者b)这个控件的原始作者不知道他在做什么。你没有提供足够的信息让我知道你真正面临的是哪种情况。

但总的来说,你不能为绑定公开计算属性的原因是,计算属性通常没有setter。设置一个值被计算出来的属性是没有意义的。

如果有其他属性的值需要在此属性更改时更新,则正确的方法(或至少符合依赖属性设计的方法)是在依赖属性的回调函数中处理这些更新,这也是回调函数的作用。


你说得完全正确。我试图绑定的属性并不是为此目的而设计的。我找到了另一个本质上相同的属性,它是一个DP,我可以将其绑定。 不幸的是,绑定根本没有起作用,但这是另一天花在调试上的故事...(我可能也会问这个问题,但不在这里) - kubal5003

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接