WPF双向绑定到属性的属性以替换父属性

mar*_*yxl 3 c# data-binding wpf dependency-properties inotifypropertychanged

我有一个使用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>
Run Code Online (Sandbox Code Playgroud)

代码隐藏:

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)));
}
Run Code Online (Sandbox Code Playgroud)

我想的是将TextBoxes直接绑定到TestPoint属性并使用IValueConverter仅过滤掉特定成员,但是在ConvertBack方法中存在问题,因为在修改X值时Y值不再存在.

我觉得必须有一个非常简单的解决方案,我没有得到.

编辑:

上面的代码只是一个简化的例子,实际应用程序比这更复杂.复合类型有大约7个成员,并且通常在应用程序中使用,因此将其拆分为单个成员感觉不对.另外我想依赖依赖属性的OnChanged事件来调用其他更新,所以我真的需要替换整个类.

Flo*_*loc 7

你为什么不使用访问器?

public partial class MainWindow : Window
{
    public Point TestPoint
    {
        get { return (Point)GetValue(TestPointProperty); }
        set { SetValue(TestPointProperty, value); }
    }

    public double TestPointX
    {
        get { return this.TestPoint.X; }
        set
        { 
            SetValue(TestPointProperty, new Point(value, this.TestPointY);
        }
    }

    public double TestPointY
    {
        get { return this.TestPoint.Y; }
        set
        { 
            SetValue(TestPointProperty, new Point(this.TestPointX, value);
        }
    }

    public static readonly DependencyProperty TestPointProperty = DependencyProperty.Register("TestPoint", typeof(Point), typeof(MainWindow), new PropertyMetadata(new Point(1.0, 1.0)));
}
Run Code Online (Sandbox Code Playgroud)

在你的XAML中:

<Window ...>
<StackPanel>
        <TextBox Text="{Binding TestPointX, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}, StringFormat=\{0:F\}}"/>
        <TextBox Text="{Binding TestPointY, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}, StringFormat=\{0:F\}}"/>
        <Label Content="{Binding TestPoint, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}"/>
    </StackPanel>
</Window>
Run Code Online (Sandbox Code Playgroud)