0

I am pretty new to WPF... So I need to bind a lines X1 and Y1 properties with an ellipses canvas.left and canvas.top property......

In XAML it works fine...

XAML Code

<Ellipse x:Name="tst" Width="40" Height="40" Canvas.Left="150" Canvas.Top="150" Stroke="Blue" StrokeThickness="2" MouseMove="adjustRoute"/>
<Line X1="{Binding ElementName=tst, Path=(Canvas.Left)}" Y1="{Binding ElementName=tst, Path=(Canvas.Top)}" X2="300" Y2="200" Stroke="Blue" StrokeThickness="2"/>

But I need to do it in the Code Behind Using C#

So I did this

temp = new Line();
tempe = new Ellipse();
tempe.Fill = Brushes.Transparent;
tempe.Stroke = Brushes.Blue;
tempe.StrokeThickness = 1;
tempe.Width = 20;
tempe.Height = 20;
Canvas.SetLeft(tempe, currentPoint.X-10);
Canvas.SetTop(tempe, currentPoint.Y-10);
tempe.MouseMove += adjustRoute;
Binding binding = new Binding { Source = tempe, Path = new PropertyPath(Canvas.LeftProperty), UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged };
temp.SetBinding(Line.X1Property, binding);
Binding binding2 = new Binding { Source = tempe, Path = new PropertyPath(Canvas.TopProperty), UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged };
temp.SetBinding(Line.Y1Property, binding2);
temp.Stroke = Brushes.Blue;
temp.StrokeThickness = 2;
temp.X1 = currentPoint.X;
temp.Y1 = currentPoint.Y;
temp.X2 = currentPoint.X + 200;
temp.Y2 = currentPoint.Y + 200;
testcanv.Children.Add(temp);
testcanv.Children.Add(tempe);

But it doesn't update the line position when I move the ellipse(in XAML it updates)....

Here currentPoint is the point I am capturing with my mouse click to draw the shapes during runtime and adjustRoute is the function to move them on drag

What did I do wrong here?

Thanks

d3fault
  • 3
  • 4
  • I guess you will have to handle the `UpdateSourceTrigger` from the binding. You can do that by setting the `UpdateSourceTrigger` of the dependencyProperty that you are binding to, to `OnPropertyChanged`, and then you implement the `INotifyPropertyChanged` interface in your Code-Behind. – Luchspeter May 04 '20 at 19:56
  • Here is a link if you want to handle the updates explicitley: https://www.wpf-tutorial.com/data-binding/the-update-source-trigger-property/ – Luchspeter May 04 '20 at 19:57
  • Here is the solution with the INotifyPropertyChange interface: https://stackoverflow.com/a/1316417/7274172 – Luchspeter May 04 '20 at 19:57
  • @Luchspeter This has nothing to do with UpdateSourceTrigger, which is only relevant for TwoWay Bindings. Also INotifyPropertyChange is irrelevant, because the source properties are depedency properties. – Clemens May 04 '20 at 19:58
  • @Clemens oh okey - thanks for the hint. But shouldn't you be able to bind a property to `Canvas.Left` and handle the updating like that? – Luchspeter May 04 '20 at 20:01
  • You should be able to bind, of course. But the Binding is all you need to do. – Clemens May 04 '20 at 20:01

1 Answers1

0

Make sure you create the Line and Ellipse elements only once, and assign the Bindings only once. Assign the MouseMove handler to the Canvas instead of the Ellipse:

private Line line;
private Ellipse ellipse;

public MainWindow()
{
    InitializeComponent();

    line = new Line
    {
        Stroke = Brushes.Blue,
        StrokeThickness = 2
    };

    ellipse = new Ellipse
    {
        Stroke = Brushes.Blue,
        StrokeThickness = 1,
        Width = 20,
        Height = 20,
        Margin = new Thickness(-10)
    };

    Binding xBinding = new Binding
    {
        Source = ellipse,
        Path = new PropertyPath(Canvas.LeftProperty)
    };
    line.SetBinding(Line.X1Property, xBinding);

    Binding yBinding = new Binding
    {
        Source = ellipse,
        Path = new PropertyPath(Canvas.TopProperty)
    };
    line.SetBinding(Line.Y1Property, yBinding);

    testcanv.Children.Add(line);
    testcanv.Children.Add(ellipse);

    testcanv.Background = Brushes.Transparent;
    testcanv.MouseMove += adjustRoute;
}

private void adjustRoute(object sender, MouseEventArgs e)
{
    var p = e.GetPosition(testcanv);
    Canvas.SetLeft(ellipse, p.X);
    Canvas.SetTop(ellipse, p.Y);
}
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • Sorry. I was being really stupid.. The problem was that I have set the lines X1 and Y1 properties to current position AFTER the Binding assignment which was discarding my bindings and resetting the X1 and Y1 properties to current position.. That's why it was not updating... All I needed to do was move those X1 Y1 X2 Y2 assignments before the binding assignment.. That solved the problem.... – d3fault May 04 '20 at 22:35