简体   繁体   中英

WPF bind point to UserControl

I have a user control that contains 2 DoubleUpDown , I have bound point to that controls

<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}" />

controls get updated pretty well when I change Value from outside, but Value stays unchanged when I change controls data.

I bound Value to user control from code inside

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

and Point2DEditorView.Value also changed when I insert new coordinates into controls. But that does not affect bound Value.

Point is a value type data. Because of this when you bind it to control boxing and unboxing occurs. For more information see this . So, you may easy solve this problem by creating your own class (not struct!):

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

And then bind this objects to your control and you will see that all works as you expect.

Update First of all your DoubleUpDown is'n in standart FCL and I think your problem in it. There is a simple example where all works as expect. I created a simple UpDown control for it:

Point class

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();
    }

}

Test form 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>

And test form .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};
    }
}

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM