簡體   English   中英

WPF:使用畫布之間的路徑動態連接畫布上的矩形

[英]WPF: Connecting rectangles on canvas dynamically with path between

這是我第一次發布,所以對我來說很容易...

肯定有一些文章顯示了如何將線連接到塊,但是這一點有些不同。 網格將動態放置在畫布上。 我希望有一條線將按下按鈕的位置的網格連接到放置在畫布上的新網格。 但是下面的代碼不起作用。 我已經為此苦苦掙扎很長時間了。
偶然地,我發現在按鈕事件處理程序中拋出的消息框將使其正常工作。 我發現這是在不同時間運行的線程造成的,但是在與task.delay / thread.sleep / async / await弄亂之后,我找不到解決方案。
我使用的是自定義類,因為這是大型程序的簡化版本,我希望示例中具有類似的功能以反映可能的錯誤,但省去了不必要的部分。 我將此作為最后的手段,在此先感謝您提供的任何幫助。 首先是CS代碼

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Grid1 g = myCanvas.CreateGrid();
            ContentControl1 cc = myCanvas.CreateCC();
            Button1 b = myCanvas.CreateButton1();

            Grid1.SetColumn(cc, 0);
            Grid1.SetRow(cc, 0);
            Grid1.SetColumn(b, 1);
            Grid1.SetRow(b, 1);
            g.Children.Add(cc);
            g.Children.Add(b);

            Canvas1.SetLeft(g, 500);
            Canvas1.SetTop(g, 5);
            myCanvas.Children.Add(g);
        }

    }

    public class Button1 : Button
    {

        protected override void OnClick()
        {

            Grid1 old_g = (Grid1)VisualTreeHelper.GetParent(this as DependencyObject);
            Canvas1 cnv = (Canvas1)VisualTreeHelper.GetParent(old_g as DependencyObject);
            Grid1 g = cnv.CreateGrid();
            ContentControl1 cc = cnv.CreateCC();
            Button1 b = cnv.CreateButton1();

            Grid1.SetColumn(cc, 0);
            Grid1.SetRow(cc, 0);
            Grid1.SetColumn(b, 1);
            Grid1.SetRow(b, 1);
            g.Children.Add(cc);
            g.Children.Add(b);

            Canvas1.SetLeft(g, 500);
            Canvas1.SetTop(g, cnv.Children.Count * 120);
            cnv.Children.Add(g);

            cnv.ConnectGrids(old_g, g);
        }


    }

    public class Canvas1 : Canvas
    {
        public Grid1 CreateGrid()
        {
            Grid1 g = new Grid1() { Width = 100, Height = 20, Background = Brushes.White };
            g.HorizontalAlignment = HorizontalAlignment.Center;
            g.VerticalAlignment = VerticalAlignment.Center;
            g.ShowGridLines = false;

            ColumnDefinition colDef1 = new ColumnDefinition();
            ColumnDefinition colDef2 = new ColumnDefinition() { Width = new GridLength(20) };
            g.ColumnDefinitions.Add(colDef1);
            g.ColumnDefinitions.Add(colDef2);

            RowDefinition rowDef1 = new RowDefinition();
            g.RowDefinitions.Add(rowDef1);
            return g;
        }

        public ContentControl1 CreateCC()
        {
            ContentControl1 cc = new ContentControl1()
            {
                VerticalContentAlignment = VerticalAlignment.Stretch,
                HorizontalContentAlignment = HorizontalAlignment.Stretch,
                BorderBrush = Brushes.BlueViolet,
            };
            return cc;
        }

        public Button1 CreateButton1()
        {
            Button1 b = new Button1()
            {
                VerticalContentAlignment = VerticalAlignment.Stretch,
                HorizontalContentAlignment = HorizontalAlignment.Stretch,
                BorderBrush = Brushes.Red
            };
            return b;
        }

        public void ConnectGrids(Grid1 g1, Grid1 g2)
        {
            Canvas1 cnv = (Canvas1)VisualTreeHelper.GetParent(g1 as DependencyObject);
            Transform transform1 = (Transform)g1.TransformToVisual(cnv as Visual);
            Transform transform2 = (Transform)g2.TransformToVisual(cnv as Visual);

            Point StartPoint1 = transform1.Transform(new Point(g1.Width, g1.Height / 2.0));
            Point EndPoint1 = transform2.Transform(new Point(g2.Width, g2.Height / 2.0));


            var lineGeometry = new LineGeometry()
            {
                StartPoint = StartPoint1,
                EndPoint = EndPoint1
            };

            var path = new Path()
            {
                Data = lineGeometry,
                Stroke = new SolidColorBrush(Colors.Black),
            };

            cnv.Children.Add(path);

        }

    }

    public class ContentControl1 : ContentControl
    {

    }

    public class Grid1 : Grid
    {

    }


}

然后是xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local ="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="1000" Width="1000">
    <DockPanel>
        <Button DockPanel.Dock="Top" Width="100" Height="20" Content="Start" Click="Button_Click"/>
        <ScrollViewer HorizontalScrollBarVisibility="Visible" Width="901" x:Name="_scrollViewer" Margin="0,5,0,25">
            <local:Canvas1 Background="Gray" Height="1000" Width="1000" x:Name="myCanvas"/>
        </ScrollViewer>
    </DockPanel>
</Window>

如何成功將網格與路徑連接?

我愛我解決了這個/討厭的問題,不得不回答自己的愚蠢問題...

太簡單了。 UpdateLayout()。 在渲染對象之前,它們不會更改位置,因此該行將移至其原來的位置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM