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; } } 
  1. 你必须得到每个盒子的位置;
  2. 在盒子之间画一条Path ;
  3. 重绘框上的拖放…

带有两个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), }); }