【问题标题】:WPF C# Canvas Drawing Line connecting buttonsWPF C#画布画线连接按钮
【发布时间】:2013-08-05 05:37:41
【问题描述】:

我正在测试如何在单击按钮时绘制一条将按钮连接到另一个按钮的线,我对坐标和 settop setleft 感到困惑,它们实际上是如何工作的。我知道我们必须设置线的X2Y2(起点与终点相减),但我真的很困惑要减去什么以及如何做到这一点。

这是迄今为止我尝试过的:

 int k = 20;
 for (int i = 0; i < 4; i++)
 {
      Button btn = new Button();
      btn.Content = i.ToString();
      btn.Height = 20;
      btn.Width = 20;
      Canvas.SetTop(btn,k); // 20
      Canvas.SetLeft(btn, 20); // 10 
      Canvas1.Children.Add(btn);
      btn.PreviewMouseDown += (source, e) =>
      {
          // No idea how to set X2 , Y2 for the line's end point.
          Line line = new Line();
          //line.X2 = ;
          //line.Y2 = ;
          line.Stroke = Brushes.Red;
          line.StrokeThickness = 4;
          Canvas.SetLeft(line,40); // Suppose this is where the line should start 
          Canvas.SetTop(line ,40); // for button " 0 " .
          Canvas1.Children.Add(line);
      };
      k += 20;
 }
 for (int i = 0; i < 4; i++)
 {
      Button btn2 = new Button();
      btn2.Content = i.ToString();
      btn2.Height = 20;
      btn2.Width = 20;
      Canvas.SetTop(btn2, k); // 20
      Canvas.SetRight(btn2, 20); // 10
      Canvas1.Children.Add(btn2);
      btn2.PreviewMouseDown += (source, e) =>
      {
          //Draw Line to connect here.
      };
      k += 20;
  }

我正在尝试从 btn 到 btn2 画一条线。

另外,我如何将按钮调整为同一级别,现在右侧按钮 (btn2) 略低于左侧按钮 (btn),我想画一条线将右侧按钮连接到单击按钮 0 时的左侧按钮,因此 0 将画一条线到 0 。

【问题讨论】:

  • 不要在 WPF 的过程代码中创建或操作 UI 元素。在 WPF 中,不需要也不需要在类型的东西背后可怕的 winforms 代码。请参阅我的示例1234,了解在 WPF 中执行此操作的正确方法。
  • +1 这些示例演示了在 WPF 中执行此操作的更清晰/更正确的方法。

标签: c# wpf button canvas line


【解决方案1】:

虽然您可以通过移动Canvas 来做到这一点,但您最好使用Buttons 本身在Canvas 上的位置。

基本上,您需要有两组坐标,即您的LineStartLineEnd,在这种情况下,它们将从您单击的两个不同的Buttons 中获得。

您可以使用Point location = ((Button)source).TransformToAncestor(Canvas1).Transform(new Point(0, 0)) 来获取被点击按钮相对于父Canvas 的位置。

然后您需要执行类似的操作来查找您单击的原始对象的位置(您似乎没有存储该对象)。然后,您可以通过设置 X1, X2, Y1, Y2 值在计算的两个 Points 之间简单地画一条线。

调整你的例子,你可以做这样的事情(只是为了演示):

public partial class MainWindow : Window
{
    public Button LastClicked { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        InitButtons();
    }


    public void InitButtons()
    {
        int k = 20;

        for (int i = 0; i < 4; i++)
        {
            Button btn = new Button();
            btn.Content = i.ToString();
            btn.Height = 20;
            btn.Width = 20;
            Canvas.SetTop(btn, k); // 20
            Canvas.SetLeft(btn, 20); // 10 
            Canvas1.Children.Add(btn);
            btn.PreviewMouseDown += (source, e) =>
            {
                if (LastClicked != null)
                {
                    // Get button locations.
                    Point LastClickedLocation = LastClicked.TransformToAncestor(Canvas1).Transform(new Point(0, 0));
                    Point ThisClickedLocation = ((Button)source).TransformToAncestor(Canvas1).Transform(new Point(0, 0));

                    // Stop same side lines.
                    if (LastClickedLocation.X != ThisClickedLocation.X)
                    {
                        Line line = new Line();

                        line.X1 = LastClickedLocation.X;
                        line.Y1 = LastClickedLocation.Y + btn.Height / 2; // Button Middle.
                        line.X2 = ThisClickedLocation.X + btn.Width; // Adjust Left side.
                        line.Y2 = ThisClickedLocation.Y + btn.Height / 2; // Button Middle.

                        line.Stroke = Brushes.Red;
                        line.StrokeThickness = 4;

                        Canvas1.Children.Add(line);
                    }
                }

                LastClicked = (Button)source;
            };
            k += 20;
        }

        k = 20; // Reset k, this is why your buttons weren't aligned.

        for (int i = 0; i < 4; i++)
        {
            Button btn2 = new Button();
            btn2.Content = i.ToString();
            btn2.Height = 20;
            btn2.Width = 20;
            Canvas.SetTop(btn2, k); // 20
            Canvas.SetRight(btn2, 20); // 10
            Canvas1.Children.Add(btn2);

            btn2.PreviewMouseDown += (source, e) =>
            {
                if (LastClicked != null)
                {
                    // Get button locations.
                    Point LastClickedLocation = LastClicked.TransformToAncestor(Canvas1).Transform(new Point(0, 0));
                    Point ThisClickedLocation = ((Button)source).TransformToAncestor(Canvas1).Transform(new Point(0, 0));

                    // Stop same side lines.
                    if (LastClickedLocation.X != ThisClickedLocation.X)
                    {
                        Line line = new Line();

                        line.X1 = LastClickedLocation.X + btn2.Width; // Adjust Left side.
                        line.Y1 = LastClickedLocation.Y + btn2.Height / 2; // Button Middle.
                        line.X2 = ThisClickedLocation.X;
                        line.Y2 = ThisClickedLocation.Y + btn2.Height / 2; // Button Middle.

                        line.Stroke = Brushes.Red;
                        line.StrokeThickness = 4;

                        Canvas1.Children.Add(line);
                    }
                }

                LastClicked = (Button)source;
            };
            k += 20;
        }
    }
}

我不建议使用这个确切的代码,因为它在处理Button 的点击和决定何时绘制线条方面并不是特别聪明,但它应该演示绘制和获取你所追求的坐标。

【讨论】:

  • 感谢您的努力,但最后点击的是什么?最后点击按钮的坐标?
  • 我在示例中遗漏了这一点,它只是一个类级别的 Button 属性,用于保存您最后点击的内容(我已经修改了示例)。
  • 嗨,感谢您的努力和时间。它工作得很好,但我正在寻找就像 0 连接到 0 , 1 连接到 1 .. 所以现在如果我点击 0 到 0 然后 1 ,它将 0 连接到 1 形成 Z 线。如果我要在按钮中添加边距,我也必须考虑边距?
  • 您可以尝试比较 Button.Content 属性以检查相同的内容。我相信你必须考虑到利润。
猜你喜欢
  • 1970-01-01
  • 2013-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多