将控件位置绑定到另一个路径
本文关键字:另一个 路径 绑定 控件 位置 | 更新日期: 2023-09-27 18:00:52
我有一个Path,他的数据来自LineGeometry。我还有一个TextBlock,它是在创建路径时创建的。让TextBlock的位置跟随Path的位置的正确方法是什么?
有很多方法
- 在自定义面板中包含Path和TestBlock,并实现MeasureOverride和ArrangeOverride
- 使用已存在的面板(Grid、StackPanel等(
- 听Path对象的LayoutUpdated,然后使用TranslatePoint方法定位TextBlock
每种方式都有其缺点和优点,这取决于整个窗口的布局以及路径的布局变化的动态性。
最简单的解决方案可能是将Path和TextBlock放入一个公共容器中,该容器在TextBlock上执行必要的布局。这可能是一个网格:
<Canvas>
<Grid>
<Path ... />
<TextBlock Text="Label" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Canvas>
您还可以通过将TextBlock的RenderTransform
(或LayoutTransform
(绑定到Path的Geometry
来相对于Path的中心定位TextBlock,并使用绑定转换器进行实际计算。转换器将例如将Geometry转换为TranslateTransform
。请注意,它甚至不要求几何图形是LineGeometry。它只是使用几何体的Bounds
。但是,您可以根据几何体的实际类型进行任何专门的计算。
public class GeometryCenterConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var result = new TranslateTransform();
var geometry = value as Geometry;
if (geometry != null)
{
result.X = (geometry.Bounds.Left + geometry.Bounds.Right) / 2;
result.Y = (geometry.Bounds.Top + geometry.Bounds.Bottom) / 2;
}
return result;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
你可以这样写绑定:
<Path Name="path" ... />
<TextBlock Text="Label"
RenderTransform="{Binding Path=Data, ElementName=path,
Converter={StaticResource GeometryCenterConverter}}"/>
请注意,上面的示例没有考虑TextBlock的任何对齐。如果需要居中或右下对齐,则可能需要更复杂的绑定(可能是MultiBinding(,或者可以将所有元素放在Canvas中,并在TextBlock上适当地设置Canvas.Left
和Canvas.Top
。