LineGeometry からデータを取得するパスがあります。パスの作成時に作成される TextBlock もあります。TextBlock の位置を Path の位置に追従させる正しい方法は何ですか?
2 に答える
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.
方法はいくらでもある
- カスタム パネルに Path と TestBlock を含め、MeasureOverride と ArrangeOverride を実装する
- 既存のパネル (Grid、StackPanel など) を使用します。
- Path オブジェクトの LayoutUpdated をリッスンし、TranslatePoint メソッドを使用して TextBlock を配置します。
それぞれの方法には欠点と利点があり、ウィンドウ全体がどのようにレイアウトされているか、およびパスのレイアウトがどの程度動的に変化するかによって異なります。