在不同的布局容器上画一条线
本文关键字:一条 布局 | 更新日期: 2023-09-27 17:56:40
我正在构建一个 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>
我的要求是通过一行将 Button1 连接到 ButtonA、B 或 C,但我不知道怎么做。根据我通常的研究,人们使用 Canvas 并连接该 Canvas 中托管的控件,并使用附加的属性 Canvas.SetTop 和 Canvas.SetLeft 将控件放置在容器内。我尝试用画布包装我的DockPanel,但没有成功。
我的问题是:是否可以绘制连接不同类型布局的控件的线条?(在我的情况下 DockPanel-Grid-UniformGrid)或者实现此目的的替代或更标准的方法是什么。我还尝试获取相对于 DockPanel 的控制位置,但也没有工作......
提前致谢
基于Charles Petzold的"网格外思考"文章,我最终得到了这样的结构:
<UserControl ... >
<Grid ... >
<local:SimpleUniformGrid ... >
<Button ... />
<Button ... />
...
</local:SimpleUniformGrid>
<Canvas>
<Path ... />
<Path ... />
<Path ... />
</Canvas>
</Grid>
</UserControl>
关键段落是这样的:
"在处理 LayoutUpdated 事件时,您不想做任何会导致另一个布局传递并让您卷入无限递归的事情。这就是 Canvas 派上用场的地方:因为它总是向其父级报告零大小,所以您可以在不影响布局的情况下更改 Canvas 中的元素。
除此之外,我还使用了Denis Vuyka MyThumb类,来自他的Dragable Objects文章
。创建行时的起点和终点可以使用 GeneralTransform 类确定,如本文所述:
GeneralTransform transform = thumb.TransformToAncestor(this);
Point rootPoint = transform.Transform(new Point(0, 0));
这里的关键教训是了解 Canvas 不占用网格内的任何空间,因此您可以将其用作存储 Paths/LineGeometry 的容器,并在视图中的任何坐标处显示它们,无论源/目标控件是否属于不同的容器。