【发布时间】:2012-11-29 10:42:39
【问题描述】:
我有一个DataGrid 和一个视图模型 (MyViewModel1)。 DataGrid 绑定到 MyViewModel1 的 Items 属性。约束是我不能碰MyViewModel1和MyClass1的代码。
public class MyViewModel1 : INotifyPropertyChanged
{
...
public ObservableCollection<MyClass1> Items { get { ... } }
public int ViewModelProperty1 { get { ... } }
public int ViewModelProperty2 { get { ... } }
}
public class MyClass1 : INotifyPropertyChanged
{
...
public int Property1 { get { ... } }
public int Property2 { get { ... } }
public int Property3 { get { ... } }
}
我希望 DataGrid 不仅显示具有 3 个已知属性的 3 列,而且还显示每行的第 4 列,这取决于 Property1、Property2、Property3、ViewModelProperty1和ViewModelProperty2。举例来说,假设第 4 列是Property1 + Property2 + Property3 + ViewModelProperty1 + ViewModelProperty2。第 4 列必须显示当前值,因此如果 ViewModelProperty1 增加 1,则第 4 列也必须增加 1。我的问题是:我有什么选择来做到这一点?
我能想到这些:
使用
IMultiValueConverter并将所有因变量作为输入。这适用于示例。这里的问题是,一旦变量的相互作用变得更加复杂,例如((Property1 + 2*Property2) * Property3) ^ (ViewModelProperty1 - ViewModelProperty2),将 5 个变量放入“MultiBinding”的顺序变得很重要,并且在绑定中有很多知识会导致解决方案变得脆弱。-
使用包装器。将
DataGrid绑定到一个新类MyViewModel2,它注册到MyViewModel1上的更改,看起来像public class MyViewModel2 { public MyViewModel2(MyViewModel1 m) { ... } ... public ObservableCollection<MyClass2> Items { get { ... } } } public class MyClass2 : INotifyPropertyChanged { public MyClass2(MyClass1 inner) { InnerClass = inner; InnerClass.NotifyPropertyChanged += InnerClassChanged; } void InnerClassChanged(object o, PropertyChangedEventArgs) { if (PropertyChanged != null) PropertyChanged("Property4"); } public void ViewModelPropertiesChanged { if (PropertyChanged != null) PropertyChanged("Property4"); } public MyClass1 InnerClass { get; private set; } public int Property4 { get { return InnerClass.Property1+InnerClass.Property2 ... } } public event PropertyChanged; }
问题是除了我上面提到的两个(转换器和包装器)之外,还有什么方法可以解决这个问题。
我的问题不是哪种方法是解决示例的最佳方法。
【问题讨论】:
-
确实没有其他干净的方法(例如:您可以将组合数据字段放在代码隐藏中)。但是,值得注意的是,您的多值转换器可以调用另一个对象来执行值转换。这可以通过将潜在的业务逻辑带回某个共享类来使其不那么“脆弱”。
标签: c# .net wpf data-binding