在不同的布局容器中划一条线

时间:2013-01-30 23:39:45

标签: c# wpf layout

我正在构建一个C#WPF应用程序,在我的一个XAML视图中,我需要使用一行连接两个驻留在不同容器中的控件。

这是我简化的布局伪代码:

<DockPanel>
   <Grid DockPanel.Dock="Top">
      <Button Name="Button1" />
   </Grid>
   <UniformGrid Columns="3" DockPanel.Dock="Bottom">
      <StackPanel>
         <Button Name="ButtonA" />
      </StackPanel>
      <StackPanel>
         <Button Name="ButtonB" />
      </StackPanel>
      <StackPanel>
         <Button Name="ButtonC" />
      </StackPanel>
   </UniformGrid>
</DockPanel>

我的要求是通过Line将Button1连接到ButtonA,B或C,但我无法弄清楚如何。根据我的研究,人们通常使用Canvas并连接Canvas中托管的控件,并使用附加属性Canvas.SetTop和Canvas.SetLeft将控件放置在容器内。我尝试用Canvas包装我的DockPanel但是没有用。

我的问题是:是否可以绘制连接不同类型布局控件的线条? (在我的案例中,DockPanel-Grid-UniformGrid)或者是实现这一目标的替代或更标准的方法。我也尝试获得相对于DockPanel的控制位置但是也没有工作...

先谢谢

1 个答案:

答案 0 :(得分:0)

根据Charles Petzold 'Thinking outside the grid'文章,我最终得到了这样的结构:

<UserControl ... >
  <Grid ... >
    <local:SimpleUniformGrid ... >
      <Button ... />
      <Button ... />
      ...
    </local:SimpleUniformGrid>

    <Canvas>
      <Path ... /> 
      <Path ... />
      <Path ... />
    </Canvas>
  </Grid>
</UserControl>

关键段落就是这个:

“在处理LayoutUpdated事件时,你不想做任何会导致另一个布局传递并让你卷入无限递归的事情。这就是Canvas派上用场的地方:因为它总是报告零对于其父级的大小,您可以在不影响布局的情况下更改“画布”中的元素。“

除此之外,我还使用了Dragable Objects article

中的Denis Vuyka MyThumb课程。

创建线条时的起点和终点可以使用GeneralTransform类来确定,如this article中所述:

    GeneralTransform transform = thumb.TransformToAncestor(this);
    Point rootPoint = transform.Transform(new Point(0, 0));

这里的关键教训是理解Canvas不占用Grid内部的任何空间,因此您可以将其用作存储Paths / LineGeometry的容器,并在视图中的任何坐标处显示它们,无论source /目标控件属于不同的容器。