开发者

Use Binding to connect Ellipses with a Line

I use the following Bindings to connect two Ellipses with a line:

Line l = new Line();
l.Stroke = Brushes.Green;
l.StrokeThickness = 3;
Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
x1.Source = y1.Source = e;
x2.Source = y2.Source = e1;
l.SetBinding(Line.X1Property, x1);
l.SetBinding(Line.Y1Property, y1);
l.SetBinding(Line.X2Property, x2);
l.SetBinding(Line.Y2Property, y2);
Dependencies.Children.Add(l);

This works great, but the problem is, the lines are drawn on the left top of the Ellipse. I'd like to use the center of the Ellipse. Therefore I would 开发者_如何转开发have to add Ellipse#width / 2 to the x property. But how can I do that?


You can use IValueConverter to change/transform values while Binding.

Here is something I cooked up:

Canvas Dependencies = new Canvas();
Ellipse e1 = new Ellipse() { Width = 200, Height = 200, Stroke = Brushes.Red, StrokeThickness = 1 };
Ellipse e2 = new Ellipse() { Width = 200, Height = 200, Stroke = Brushes.Red, StrokeThickness = 1 };
Line l = new Line();

l.Stroke = Brushes.Green;
l.StrokeThickness = 3;

Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty); x1.Converter = new MyConverter(); x1.ConverterParameter = e1;
Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty); y1.Converter = new MyConverter(); y1.ConverterParameter = e1;
Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty); x2.Converter = new MyConverter(); x2.ConverterParameter = e2;
Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty); y2.Converter = new MyConverter(); y2.ConverterParameter = e2;

x1.Source = y1.Source = e1;
x2.Source = y2.Source = e2;

l.SetBinding(Line.X1Property, x1);
l.SetBinding(Line.Y1Property, y1);
l.SetBinding(Line.X2Property, x2);
l.SetBinding(Line.Y2Property, y2);

Dependencies.Children.Add(e1);
Dependencies.Children.Add(e2);
Dependencies.Children.Add(l);

SizeChangedEventHandler act = (Object s, SizeChangedEventArgs args) =>
{
    BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
    BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
    BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
    BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
};

e1.SizeChanged += act;
e2.SizeChanged += act;

Canvas.SetLeft(e1, 200);
Canvas.SetTop(e1, 200);

Canvas.SetLeft(e2, 500);
Canvas.SetTop(e2, 500);

Grid2.Children.Add(Dependencies);

Converter:

public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Ellipse e = parameter as Ellipse;
        Double d = (Double)value;

        return d + (e.ActualWidth / 2);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Ellipse e = parameter as Ellipse;
        Double d = (Double)value;

        return d - (e.ActualWidth / 2);
    }
}

Note that the converter considers Ellipse.Width only. You will need to modify it to make it work correctly.


Your binding now depends on two properties, the Canvas.Left (or Canvas.Top), and the Ellipse.ActualWidth (or height). To achieve this you can use a multibinding. See the following examples:

http://www.switchonthecode.com/tutorials/wpf-tutorial-using-multibindings

However, there are other, possibly simpler alternatives. You could use a render transform to translate your ellipses by an X position which is half of its width and a Y position that is half of its height, to centre your ellipse at the position given by Canvas.Left and canvas.Top

Regards, Colin E.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜