WPF绑定指向UserControl

时间:2013-10-11 06:07:37

标签: c# wpf binding user-controls

我有一个包含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}" />
当我从外部更改Value时,

控件的更新非常好,但是当我更改控件数据时,Value保持不变。

我从内部代码

中将Value绑定到用户控件
Point2DEditorView editor = new Point2DEditorView();
Binding binding = new Binding("Value");
binding.Mode = BindingMode.TwoWay;
editor.SetBinding(Point2DEditorView.ValueProperty, binding);
当我将新坐标插入控件时,

Point2DEditorView.Value也发生了变化。但这并不影响约束价值。

1 个答案:

答案 0 :(得分:0)

Point是值类型数据。因此,当你将它绑定到控制装箱并发生拆箱时。有关更多信息,请参阅this。所以,你可以通过创建自己的类(而不是struct!)来轻松解决这个问题:

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

然后将这些对象绑定到您的控件上,您将看到所有对象都按预期工作。

<强>更新 首先,你的DoubleUpDown是非常标准的整箱,我认为你的问题在于它。有一个简单的例子,其中所有工作都如期望。我为它创建了一个简单的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));
    }
}

UpDown 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>

UpDown .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>

UpDown .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};
    }
}

希望这有帮助。