将控制位置绑定到另一个路径

时间:2013-02-24 03:39:16

标签: c# wpf controls

我有一个Path的数据来自LineGeometry。我还有一个在创建路径时创建的TextBlock。使TextBlock的位置遵循Path的位置的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

有很多方法

  • 在自定义面板中包含Path和TestBlock,并实现MeasureOverride和ArrangeOverride
  • 使用已存在的面板(Grid,StackPanel等)
  • 收听Path对象的LayoutUpdated,然后使用TranslatePoint方法
  • 定位TextBlock

每种方式都有其缺点和优点,这取决于整个窗口的布局方式以及路径布局变化的动态性

答案 1 :(得分:0)

最简单的解决方案是将Path和TextBlock放入一个在TextBlock上执行必要布局的公共容器中。这可能是一个网格:

<Canvas>
    <Grid>
        <Path ... />
        <TextBlock Text="Label" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Canvas>

您还可以通过将其RenderTransform(或LayoutTransform)绑定到路径Geometry并使用binding converter进行实际计算,将TextBlock相对于路径中心定位。转换器例如将几何转换为TranslateTransform。请注意,它甚至不需要Geometry成为LineGeometry。它只使用Geometry的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中并设置Canvas.LeftCanvas.Top适当地在TextBlock上。