我有一个使用DependencyProperties(或INotifyPropertyChanged)的ViewModel,其中包含一个非常简单的复合类型属性,例如System.Windows.Point。这个简单的复合类型不使用DependencyProperties或INotifyPropertyChanged,并且打算保持这种状态(我无法控制它)。
现在我想创建双向数据绑定到Point的X和Y属性,但是当其中一个属性被更改时,我希望整个Point类被替换,而不仅仅是更新成员。
以下是示例代码:
我想的是直接将两个文本框绑定到TestPoint属性,并使用IValueConverter过滤出特定成员,但是在ConvertBack方法中会有问题,因为修改X值时不再存在Y值。
我感觉这一定有一个非常简单的解决方案,但我还没有想到。
编辑:上面的代码只是一个简化的示例,实际应用比这更复杂。复合类型有大约7个成员,并且在整个应用程序中通常被广泛使用,因此将其拆分为单个成员并不合适。此外,我希望依靠依赖属性的OnChanged事件来调用其他更新,因此我真的需要替换整个类。
现在我想创建双向数据绑定到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)));
}
我想的是直接将两个文本框绑定到TestPoint属性,并使用IValueConverter过滤出特定成员,但是在ConvertBack方法中会有问题,因为修改X值时不再存在Y值。
我感觉这一定有一个非常简单的解决方案,但我还没有想到。
编辑:上面的代码只是一个简化的示例,实际应用比这更复杂。复合类型有大约7个成员,并且在整个应用程序中通常被广泛使用,因此将其拆分为单个成员并不合适。此外,我希望依靠依赖属性的OnChanged事件来调用其他更新,因此我真的需要替换整个类。
X
和Y
属性时,请注意潜在的内存泄漏。由于Point
不是INotifyPropertyChanged
,也没有DependencyProperties
,因此绑定将使用PropertyDescriptor
,如果绑定不是OneTime
,则可能会导致泄漏:https://dev59.com/3WMl5IYBdhLWcg3wRlLo - wkl