做一行在Silverlight中连接两个物体 [英] make line that connects two objects in silverlight

查看:93
本文介绍了做一行在Silverlight中连接两个物体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎么能连接这些实体盒?

how can I connect these entity boxes?

创建的包装盒,并且可以拖动。现在我想将它们用线或东西连接

the boxes are created by clicking a button and they can be dragged. Now I want to connect them with a line or something.

推荐答案

下面是一个快速和肮脏的实现:

Here is a quick and dirty implementation:

这表示连接类:

public partial class Connection
{
    public MyBox Box1 { get; set; }
    public MyBox Box2 { get; set; }
    public Line Line { get; set; }
}

要创建一个新的连接,我使用的基本形式:名称源,目标和一个按钮:

To create a new connection I've used a basic form: name of source, destination and a button:

<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代码:

And the RefreshLinesPositions code:

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每当框被移动:

And you call RefreshLinesPositions whenever a box is moved:

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();
}



我用这个来表示节点:

I've used this for representing nodes:

public partial class Node
{
    public string Title { get; set; }
    public TextBox Text { get; set; }
}

这篇关于做一行在Silverlight中连接两个物体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆