WPF如何在两个分量之间绘制箭头

问题描述 投票:0回答:1

我为程序创建了一个自定义树(由于各种原因无法使用树视图),但尚不清楚哪个组件是哪个孩子的父级。我想添加一个可以这样称呼的箭头:

var arrow = CreateArrowBetween(c1,c2)

但是我不知道如何,有人可以帮助我还是给我带头?ps:目前该元素位于网格上

wpf drawing
1个回答
0
投票

以下示例显示了如何在容器(例如,FrameworkElement)中托管的两个Grid元素之间绘制居中箭头。

这是非常基本的,需要进行改进以检测元素是堆叠还是彼此相邻。现在,该算法假定使用堆叠元素,并将箭头水平居中放置在元素底部/顶部边缘上。如果元素彼此相邻,则可能需要对左/右边缘进行拼接。MainWindow.xaml

<Window>
  <Grid x:Name="Container">
    <TextBox x:Name="TextBox" Text="Some text" Height="20" />
    <TextBlock x:Name="TextBlock" Margin="0,100,0,0" Text="More text" />
  </Grid>
</Window>

MainWindow.xaml.cs

partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();
    this.Loaded += OnLoaded;
  }

  private void OnLoaded(object sender, RoutedEventArgs e)
  {
    CreateArrowBetween(this.TextBlock, this.TextBox, this.Container);
  }

  // The arrow will point from start to end
  private void CreateArrowBetween(FrameworkElement startElement, FrameworkElement endElemend, Panel parentContainer)
  {
    SolidColorBrush arrowBrush = Brushes.Red;

    // Center the line horizontally and vertically.
    // Get the positions of the controls that should be connected by a line.
    Point centeredArrowStartPosition = startElement.TransformToAncestor(parentContainer)
      .Transform(new Point(startElement.ActualWidth / 2, startElement.ActualHeight / 2));

    Point centeredArrowEndPosition = endElemend.TransformToAncestor(parentContainer)
      .Transform(new Point(endElemend.ActualWidth / 2, endElemend.ActualHeight / 2));

    // Draw the line between two controls
    var arrowLine = new Line()
    {
      Stroke = Brushes.Red,
      StrokeThickness = 2,
      X1 = centeredArrowStartPosition.X,
      Y2 = centeredArrowEndPosition.Y,
      X2 = centeredArrowEndPosition.X,
      Y1 = centeredArrowStartPosition.Y
    };
    parentContainer.Children.Add(
      arrowLine);

    // Create the arrow tip of the line. The arrow has a width of 8px and a height of 8px,
    // where the position of arrow tip and the line's end are the same
    var arrowLineTip = new Polygon() {Fill = Brushes.Red};
    var leftRectanglePoint = new Point(centeredArrowEndPosition.X - 4, centeredArrowEndPosition.Y + 8);
    var rightRectanglePoint = new Point(
      centeredArrowEndPosition.X + 4,
      centeredArrowEndPosition.Y + 8);
    var rectangleTipPoint = new Point(centeredArrowEndPosition.X, centeredArrowEndPosition.Y);
    var myPointCollection = new PointCollection
    {
      leftRectanglePoint, 
      rightRectanglePoint, 
      rectangleTipPoint
    };
    arrowLineTip.Points = myPointCollection;
    parentContainer.Children.Add(
      arrowLineTip);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.