回答
这里是一个快速和肮脏的实施:
表示连接类:
public partial class Connection
{
public MyBox Box1 { get; set; }
public MyBox Box2 { get; set; }
public Line Line { get; set; }
}
要创建一个新的连接,我使用的基本形式:来源,目的地和按钮的名称, :
<StackPanel Orientation="Horizontal" Grid.Row="3">
<TextBox Width="100" Text="{Binding From,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
<TextBlock Text=" ----> " />
<TextBox Width="100" Text="{Binding To,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
<Button Content="Connect" Click="Button_Click_2" />
</StackPanel>
这里是处理:
public string From { get; set; }
public string To { get; set; }
private IList<Connection> connections = new List<Connection>();
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:
<Canvas x:Name="Root">
<Rectangle
x:Name="rect1"
Fill="Aqua"
Width="20"
Height="20"
Canvas.Left="24"
Canvas.Top="44" />
<Rectangle
x:Name="rect2"
Fill="Red"
Width="20"
Height="20"
Canvas.Left="119"
Canvas.Top="73" />
</Canvas>
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),
});
}
这个例子是好的,但我怎么能做到这一点没有预制的对象呢?我猜想更好的方法来做这些行是通过点击一个按钮,允许从一个对象到另一个画一条线...... 这个链接上的例子是完美的,但它是在WPF,我不能把这在我的项目上:/ http://denisvuyka.wordpress。com/2007/10/13/wpf-draggable-objects-and-simple-shape-connectors/ – terrorista
您是否知道如何在拖动时使矩形调整路径? – terrorista
- 1. Snap.svg - 如何总是用一条线连接两个对象?
- 2. 在Silverlight中使用线条连接两个动态创建的形状
- 3. 连接两个JSON对象
- 4. Qt,C++绘制两个对象之间的连接线
- 5. openGL着色器:两个对象和一条线来连接它们
- 6. 动画连接AS3中对象的多条线
- 7. 用线连接Three.js中的对象
- 8. 将两个对象相互连接
- 9. 两个连接关系对象
- 10. C++无法连接两个对象
- 11. 从两个jQuery对象中连接两个附加值
- 12. 画线用两条平行线连接两条平行线的末端
- 13. 如何用一条线连接DrawRectangle中的两个点?
- 14. 画一条线连接WPF中的两个用户控件
- 15. flex 4:如何连接两条曲线?
- 16. 用AWK连接每两条线
- 17. 连接两个线程
- 18. 使用左连接和两个条件
- 19. 在svg中的两个对象之间创建线条
- 20. Codeigniter根据两个连接条件连接两个表
- 21. 如何在窗体中绘制一条线来连接vb6中的两个对象
- 22. 如何在R中使用传单连接两条坐标线
- 23. 如何在Dragcompleted上动画连接到对象的线条?
- 24. 如何在这个d3.js视觉中用一条线连接两个弧线
- 25. 如何连接两个拟合的B样条曲线?
- 26. 两个Python文件中的对象之间的连接
- 27. 连接两个不同的对象对于ArrayList的
- 28. c中两个对象列表的连接#
- 29. 在C++中连接两个自定义的字符串对象?
- 30. 有两个条件的左连接表
我收到“From”和“To”的错误,表示它不存在 – terrorista
它们只是两个字符串属性,我更新了代码。 – Pragmateek
我点击连接,但什么也没有发生,也许我做错了什么 – terrorista