make line连接silverlight中的两个对象
我该如何连接这些实体盒?
通过单击按钮创建框,可以拖动它们。 现在我想用线或类似物连接它们。
这是一个快速而又脏的实现:
表示连接的类:
public partial class Connection { public MyBox Box1 { get; set; } public MyBox Box2 { get; set; } public Line Line { get; set; } }
要创建新连接,我使用了一个基本表单:源名称,目标名称和按钮:
这是处理程序:
public string From { get; set; } public string To { get; set; } private IList connections = new List (); private void Button_Click_2(object sender, RoutedEventArgs e) { MyBox box1 = boxes.Single(b => b.Header == From); MyBox box2 = boxes.Single(b => b.Header == To); Connection conn = new Connection { Box1 = box1, Box2 = box2, Line = new Line { StrokeThickness = 1, Stroke = Brushes.Black } }; connections.Add(conn); RefreshLinesPositions(); panel.Children.Add(conn.Line); }
和RefreshLinesPositions代码:
private void RefreshLinesPositions() { foreach (Connection conn in connections) { Point p1 = conn.Box1.TranslatePoint(new Point(0, 0), panel); Point p2 = conn.Box2.TranslatePoint(new Point(0, 0), panel); double t1 = p1.Y; double b1 = p1.Y + conn.Box1.ActualHeight; double l1 = p1.X; double r1 = p1.X + conn.Box1.ActualWidth; double t2 = p2.Y; double b2 = p2.Y + conn.Box2.ActualHeight; double l2 = p2.X; double r2 = p2.X + conn.Box2.ActualWidth; if (r1 < l2) { conn.Line.X1 = r1; conn.Line.Y1 = t1 + (b1 - t1) / 2; conn.Line.X2 = l2; conn.Line.Y2 = t2 + (b2 - t2) / 2; conn.Line.Visibility = Visibility.Visible; } else if (r2 < l1) { conn.Line.X1 = r2; conn.Line.Y1 = t2 + (b2 - t2) / 2; conn.Line.X2 = l1; conn.Line.Y2 = t1 + (b1 - t1) / 2; conn.Line.Visibility = Visibility.Visible; } else if (b1 < t2) { conn.Line.X1 = l1 + (r1 - l1) / 2; conn.Line.Y1 = b1; conn.Line.X2 = l2 + (r2 - l2) / 2; conn.Line.Y2 = t2; conn.Line.Visibility = Visibility.Visible; } else if (b2 < t1) { conn.Line.X1 = l1 + (r1 - l1) / 2; conn.Line.Y1 = t1; conn.Line.X2 = l2 + (r2 - l2) / 2; conn.Line.Y2 = b2; conn.Line.Visibility = Visibility.Visible; } else { conn.Line.Visibility = System.Windows.Visibility.Collapsed; } }
每当移动一个框时你都会调用RefreshLinesPositions:
private void Box_MouseMove(object sender, MouseEventArgs e) { if (draggedBox != null) { ... RefreshLinesPositions(); } }
编辑:为节点
新的RefreshLinesPosition版本:
private void RefreshLinesPositions() { foreach (Connection conn in connections) { Point p1 = conn.Box1.TranslatePoint(new Point(0, 0), panel); Point p2 = conn.Box2.TranslatePoint(new Point(0, 0), panel); double t1 = p1.Y; double b1 = p1.Y + conn.Box1.ActualHeight; double l1 = p1.X; double r1 = p1.X + conn.Box1.ActualWidth; double t2 = p2.Y; double b2 = p2.Y + conn.Box2.ActualHeight; double l2 = p2.X; double r2 = p2.X + conn.Box2.ActualWidth; if (r1 < l2) { conn.Line.X1 = r1; conn.Line.Y1 = t1 + (b1 - t1) / 2; conn.Line.X2 = l2; conn.Line.Y2 = t2 + (b2 - t2) / 2; conn.Line.Visibility = Visibility.Visible; conn.Node1.Text.RenderTransform = new TranslateTransform(r1, t1 + (b1 - t1) / 2); conn.Node2.Text.RenderTransform = new TranslateTransform(l2 - conn.Node2.Text.ActualWidth, t2 + (b2 - t2) / 2); } else if (r2 < l1) { conn.Line.X1 = l1; conn.Line.Y1 = t1 + (b1 - t1) / 2; conn.Line.X2 = r2; conn.Line.Y2 = t2 + (b2 - t2) / 2; conn.Line.Visibility = Visibility.Visible; conn.Node1.Text.RenderTransform = new TranslateTransform(l1 - conn.Node1.Text.ActualWidth, t1 + (b1 - t1) / 2); conn.Node2.Text.RenderTransform = new TranslateTransform(r2, t2 + (b2 - t2) / 2); } else if (b1 < t2) { conn.Line.X1 = l1 + (r1 - l1) / 2; conn.Line.Y1 = b1; conn.Line.X2 = l2 + (r2 - l2) / 2; conn.Line.Y2 = t2; conn.Line.Visibility = Visibility.Visible; conn.Node1.Text.RenderTransform = new TranslateTransform(l1 + (r1 - l1) / 2, b1); conn.Node2.Text.RenderTransform = new TranslateTransform(l2 + (r2 - l2) / 2, t2 - conn.Node2.Text.ActualHeight); } else if (b2 < t1) { conn.Line.X1 = l1 + (r1 - l1) / 2; conn.Line.Y1 = t1; conn.Line.X2 = l2 + (r2 - l2) / 2; conn.Line.Y2 = b2; conn.Line.Visibility = Visibility.Visible; conn.Node1.Text.RenderTransform = new TranslateTransform(l1 + (r1 - l1) / 2, t1 - conn.Node1.Text.ActualHeight); conn.Node2.Text.RenderTransform = new TranslateTransform(l2 + (r2 - l2) / 2, b2); } else { conn.Line.Visibility = System.Windows.Visibility.Collapsed; } } }
新的事件处理程序:
private void Button_Click_2(object sender, RoutedEventArgs e) { MyBox box1 = boxes.Single(b => b.Header == From); MyBox box2 = boxes.Single(b => b.Header == To); Connection conn = new Connection { Box1 = box1, Box2 = box2, Line = new Line { StrokeThickness = 1, Stroke = Brushes.Black }, Node1 = new Node { Text = new TextBox() }, Node2 = new Node { Text = new TextBox() } }; connections.Add(conn); panel.Children.Add(conn.Line); panel.Children.Add(conn.Node1.Text); panel.Children.Add(conn.Node2.Text); RefreshLinesPositions(); }
我用它来代表节点:
public partial class Node { public string Title { get; set; } public TextBox Text { get; set; } }
- 你必须得到每个盒子的位置;
- 在盒子之间画一条
Path
; - 重绘框上的拖放…
带有两个Rectangle
简单样本:
XAML:
C# :
ConnectBoxes(Root, rect1, rect2); .... public void ConnectBoxes(Canvas container, Rectangle boxeSrc, Rectangle boxeDest) { var transform1 = boxeSrc.TransformToVisual(container); var transform2 = boxeDest.TransformToVisual(container); var lineGeometry = new LineGeometry() { StartPoint = transform1.Transform( new Point(boxeSrc.ActualWidth / 2, boxeSrc.ActualHeight / 2.0) ), EndPoint = transform2.Transform( new Point(boxeDest.ActualWidth / 2.0, boxeDest.ActualHeight / 2.0) ) }; container.Children.Add(new Path() { Data = lineGeometry, Fill = new SolidColorBrush(Colors.Brown), Stroke = new SolidColorBrush(Colors.Brown), }); }