0

I have a Path who's data comes from a LineGeometry. I also have a TextBlock that is created when the path is created. What is the correct way to get the TextBlock's position to follow the Path's position?

4

2 回答 2

0

有很多方法

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

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

于 2013-02-24T06:50:26.273 回答
0

The perhaps simplest solution would be to put the Path and the TextBlock into a common container that perform the necessary layout on the TextBlock. This could be a Grid:

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

You could also position the TextBlock relative to the Path's center by binding its RenderTransform (or LayoutTransform) to the Path's Geometry and use a binding converter for the actual calculation. The converter would for example convert a Geometry into a TranslateTransform. Note that it does not even require the Geometry to be a LineGeometry. It just uses the Geometry's Bounds. You could however do any specialized calculation, depending on the actual type of Geometry.

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();
    }
}

You would write the binding like this:

<Path Name="path" ... />
<TextBlock Text="Label"
    RenderTransform="{Binding Path=Data, ElementName=path,
                      Converter={StaticResource GeometryCenterConverter}}"/>

Note that the above example does not take any alignment of the TextBlock into account. If you need it to be centered or perhaps right- and bottom-aligned, you may need a more complex binding (perhaps a MultiBinding) or you may put all elements in a Canvas and set Canvas.Left and Canvas.Top appropriately on the TextBlock.

于 2013-02-24T10:18:57.197 回答