0

我有一个包含的用户控件2 DoubleUpDown,我有指向该控件的绑定点

<DoubleUpDown x:Name="X" Grid.Column="1" Grid.Row="0" Value="{Binding Path=Value.X, Mode=TwoWay" />
<DoubleUpDown x:Name="Y" Grid.Column="1" Grid.Row="1" Value="{Binding Path=Value.Y, Mode=TwoWay}" />

当我从外部更改值时,控件会很好地更新,但是当我更改控件数据时,值保持不变。

我从内部代码将值绑定到用户控件

Point2DEditorView editor = new Point2DEditorView();
Binding binding = new Binding("Value");
binding.Mode = BindingMode.TwoWay;
editor.SetBinding(Point2DEditorView.ValueProperty, binding);

Point2DEditorView.Value当我将新坐标插入控件时也发生了变化。但这并不影响绑定值。

4

1 回答 1

0

Point 是一个值类型的数据。因此,当您将其绑定到控制装箱和拆箱时,就会发生这种情况。有关更多信息,请参阅。因此,您可以通过创建自己的类(而不是结构!)来轻松解决这个问题:

class MyPoint
{
    public int X { set; get; }
    public int Y { set; get; }
}

然后将此对象绑定到您的控件,您将看到一切都按预期工作。

更新 首先,您的 DoubleUpDown 在标准 FCL 中,我认为您的问题在其中。有一个简单的例子,一切都按预期工作。我为它创建了一个简单的 UpDown 控件:

点类

public class Point2D : INotifyPropertyChanged
{
    private double x;
    private double y;

    public double X
    {
        set
        {
            if (value.Equals(x)) return;
            x = value;
            OnPropertyChanged();
        }
        get { return x; }
    }

    public double Y
    {
        set
        {
            if (value.Equals(y)) return;
            y = value;
            OnPropertyChanged();
        }
        get { return y; }
    }

    public event PropertyChangedEventHandler PropertyChanged;


    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

向上向下 xaml

<UserControl x:Name="doubleUpDown" x:Class="PointBind.DoubleUpDown"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" d:DesignWidth="105" Height="33">
<StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=doubleUpDown}">
    <TextBox Margin="5,5,0,5" Width="50" Text="{Binding Value}" />
    <Button x:Name="Up" x:FieldModifier="private" Margin="5,5,0,5" Content="˄" Width="20" Click="Up_Click" />
    <Button x:Name="Down" x:FieldModifier="private" Margin="0,5,0,5"  Content="˅" Width="20" Click="Down_Click" />
</StackPanel>
</UserControl>

上下.cs

public partial class DoubleUpDown : UserControl
{

    public double Value
    {
        get { return (double)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(double), typeof(DoubleUpDown), new PropertyMetadata(0.0));



    public DoubleUpDown()
    {
        InitializeComponent();
        DataContext = this;
    }

    private void Up_Click(object sender, RoutedEventArgs e)
    {
        Value++;
    }

    private void Down_Click(object sender, RoutedEventArgs e)
    {
        Value--;
    }


}

Point2DEditorView xaml

<UserControl x:Name="point2DEditorView" x:Class="PointBind.Point2DEditorView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         xmlns:local="clr-namespace:PointBind"
         d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
    <local:DoubleUpDown Value="{Binding Point.X, ElementName=point2DEditorView, Mode=TwoWay}"/>
    <local:DoubleUpDown Value="{Binding Point.Y, ElementName=point2DEditorView, Mode=TwoWay}"/>
</StackPanel>
</UserControl>

上下.cs

    public partial class Point2DEditorView : UserControl
{

    public Point2D Point
    {
        get { return (Point2D)GetValue(PointProperty); }
        set { SetValue(PointProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Point.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PointProperty =
        DependencyProperty.Register("Point", typeof (Point2D), typeof (Point2DEditorView),
            new PropertyMetadata(new Point2D {X = 10, Y = 20}));


    public Point2DEditorView()
    {
        InitializeComponent();
    }

}

测试表格 xaml

<Window x:Class="PointBind.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:PointBind"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <local:Point2DEditorView x:Name="pointEditor"/>
    <Button Content="Button" HorizontalAlignment="Left" Margin="39,121,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>

</Grid>
</Window>

并测试表格.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        pointEditor.Point = new Point2D{X = 300, Y = 400};
    }
}

希望这可以帮助。

于 2013-10-11T06:28:21.087 回答