【发布时间】:2017-05-17 06:57:42
【问题描述】:
我有一个使用 DependencyProperties(或 INotifyPropertyChanged)的 ViewModel,它具有非常简单的复合类型(如 System.Windows.Point)的属性。 简单复合类型不使用 DependencyProperties 或 INotifyPropertyChanged,它打算保持这种方式(它不在我的控制范围内)。
我现在要做的是创建与 Point 的 X 和 Y 属性的双向数据绑定,但是当其中一个发生更改时,我希望替换整个 Point 类,而不是只更新会员。
代码示例仅用于说明:
<Window ...>
<StackPanel>
<TextBox Text="{Binding TestPoint.X, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}, StringFormat=\{0:F\}}"/>
<TextBox Text="{Binding TestPoint.Y, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}, StringFormat=\{0:F\}}"/>
<!-- make following label update based on textbox changes above -->
<Label Content="{Binding TestPoint, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}"/>
</StackPanel>
</Window>
代码隐藏:
public partial class MainWindow : Window
{
public Point TestPoint
{
get { return (Point)GetValue(TestPointProperty); }
set { SetValue(TestPointProperty, value); }
}
public static readonly DependencyProperty TestPointProperty = DependencyProperty.Register("TestPoint", typeof(Point), typeof(MainWindow), new PropertyMetadata(new Point(1.0, 1.0)));
}
我的想法是将两个TextBoxes直接绑定到TestPoint属性并使用IValueConverter仅过滤掉特定成员,但是ConvertBack方法出现问题,因为修改X值时Y值不再存在。
我觉得必须有一个我没有得到的非常简单的解决方案。
编辑:
上面的代码只是一个简化的例子,实际应用比这更复杂。复合类型有大约 7 个成员,并且在整个应用程序中普遍使用,因此将其拆分为单个成员感觉不对。另外我想依靠依赖属性的 OnChanged 事件来调用其他更新,所以我真的需要替换整个类。
【问题讨论】:
-
你可以在转换器中保存其他值,你试过这样吗?
-
您的意思是作为转换器的成员吗?我没想到。我假设我需要为每个字段设置单独的转换器实例,对吗?还有安全吗?是否保证Convert期间存储的Y值在执行ConvertBack时仍然有效?
-
当绑定到
X和Y属性时,请注意潜在的内存泄漏。由于Point不是INotifyPropertyChanged并且它们不是DependencyProperties,绑定将使用PropertyDescriptor,如果绑定不是OneTime,则可能导致泄漏:stackoverflow.com/questions/18542940/… -
是的,您需要为每个字段提供单独的转换器实例(从技术上讲,对于每个 x 和 y 字段)。是的,当执行 ConverBack 时,存储的值将有效。
标签: c# wpf data-binding dependency-properties inotifypropertychanged