Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 在两个椭圆之间连接一条线_Wpf - Fatal编程技术网

Wpf 在两个椭圆之间连接一条线

Wpf 在两个椭圆之间连接一条线,wpf,Wpf,我试着在两个椭圆之间连接一条线,如果其中一个被拖动,这条线就会随之移动。我有一块画布,里面有两个堆叠面板。。。在每个stackpanel中,左边是一个椭圆。。。内容控制在中间…右边还有一个椭圆。其想法是在一个stackpanel的右椭圆与第二个stackpanel的左椭圆之间连接一条线。到目前为止,我已经有了这个功能,但似乎不能走得更远,因为用于绑定的propertypath对我来说没有太多意义。。。这就是为什么我现在有一块画布在那里 Line line = new Line(); line.S

我试着在两个椭圆之间连接一条线,如果其中一个被拖动,这条线就会随之移动。我有一块画布,里面有两个堆叠面板。。。在每个stackpanel中,左边是一个椭圆。。。内容控制在中间…右边还有一个椭圆。其想法是在一个stackpanel的右椭圆与第二个stackpanel的左椭圆之间连接一条线。到目前为止,我已经有了这个功能,但似乎不能走得更远,因为用于绑定的propertypath对我来说没有太多意义。。。这就是为什么我现在有一块画布在那里

Line line = new Line();
line.Stroke = connectedEllipse.Fill;
line.StrokeThickness = 2;

Binding x1 = new Binding();
Binding x2 = new Binding();
Binding y1 = new Binding();
Binding y2 = new Binding();

x1.Path = new PropertyPath(Canvas.LeftProperty);
x2.Path = new PropertyPath(Canvas.LeftProperty);
y1.Path = new PropertyPath(Canvas.TopProperty);
y2.Path = new PropertyPath(Canvas.TopProperty);

x1.Source = y1.Source = connectedEllipse;
x2.Source = y2.Source = (sender as Ellipse);

line.SetBinding(Line.X1Property, x1);
line.SetBinding(Line.X2Property, x2);
line.SetBinding(Line.Y1Property, y1);
line.SetBinding(Line.Y2Property, y2);

好的,我已经破解了一些不使用附加属性方法的代码。这可能不是“好”的代码,因为我在20分钟内就完成了它,但它会让你开始

MainWindow.xaml

<Window x:Class="EllipseTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:EllipseTest"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" >
    <Window.Resources>
        <ControlTemplate x:Key="template1">
            <Ellipse Width="60" Height="30" Fill="Blue" />
        </ControlTemplate>
    </Window.Resources>
    <Canvas Name="canvas">
        <my:ExtendedThumb x:Name="thumb1" Canvas.Left ="0" Canvas.Top="0" DragDelta="myThumb_DragDelta" Template="{StaticResource template1}" />
        <my:ExtendedThumb x:Name="thumb2" Canvas.Left ="50" Canvas.Top="20" DragDelta="myThumb_DragDelta" Template="{StaticResource template1}" />
    </Canvas>
</Window>

另外,我从这个链接的内容中得到了这个想法:

Hmm。。。查看附加属性,但找不到有意义的属性。因此,您可以创建一个附加属性,将其称为
PointInEllipse
。现在在设置绑定的代码隐藏中,做一些数学运算,找到椭圆内的一个点(可能是中心),然后将线的
X1Property
绑定到该点。对第二个椭圆执行相同操作,并将
X2Property
绑定到该椭圆。下面是一篇关于绑定到附加属性的文章。这有意义吗?想知道怎么做。。。我以前没有在代码隐藏中使用过绑定。你举的例子并没有暗示如何去做。但听起来这是正确的选择。另一个想法。。。如果我把每个椭圆放在它自己的画布上。。。然后,我是否能够设置线来连接画布外部、stackpanel外部的椭圆。。在初始画布上,然后回到另一个包含画布和椭圆的stackpanel?我不完全确定我是否理解你的问题,但从我的理解来看,我没有看到它的优势。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 EllipseTest
{
   /// <summary>
   /// Interaction logic for MainWindow.xaml
   /// </summary>
   public partial class MainWindow : Window
   {
      Path path;

      public MainWindow()
      {
         InitializeComponent();
      }

      private void myThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
      {
         ExtendedThumb thumb = e.Source as ExtendedThumb;
         Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange);
         Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange);
         if (thumb == thumb1)
            UpdateLine(thumb, thumb2);
         else
            UpdateLine(thumb1, thumb);
      }

      private void UpdateLine(ExtendedThumb firstThumb, ExtendedThumb secondThumb)
      {
         double left1 = Canvas.GetLeft(firstThumb);
         double top1 = Canvas.GetTop(firstThumb);

         double left2 = Canvas.GetLeft(secondThumb);
         double top2 = Canvas.GetTop(secondThumb);

         thumb1.ConnectingLine.StartPoint = new Point(left1 +firstThumb.ActualWidth / 2, top1 + firstThumb.ActualHeight / 2);
         thumb1.ConnectingLine.EndPoint = new Point(left2 + secondThumb.ActualWidth / 2, top2 + secondThumb.ActualHeight / 2);

         thumb2.ConnectingLine.StartPoint = new Point(left2 + secondThumb.ActualWidth / 2, top2 + secondThumb.ActualHeight / 2);
         thumb2.ConnectingLine.EndPoint = new Point(left1 + firstThumb.ActualWidth / 2, top1 + firstThumb.ActualHeight / 2);

      }

      private void Window_Loaded(object sender, RoutedEventArgs e)
      {
         path = new Path();
         path.Stroke = Brushes.Black;
         path.StrokeThickness = 2;

         canvas.Children.Add(path);

         LineGeometry line = new LineGeometry();
         path.Data = line;

         thumb1.ConnectingLine = line;
         thumb2.ConnectingLine = line;

         UpdateLine(thumb1, thumb2);

      }
   }
}
using System;
using System.Collections.Generic;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Linq;
using System.Text;

namespace EllipseTest
{
   public class ExtendedThumb : Thumb
   {
      public LineGeometry ConnectingLine { get; set; }

      public ExtendedThumb() : base() { ConnectingLine = new LineGeometry(); }
   }
}