A TextBlock should be centered to a position x (or y when Orientation is vertical). I implemented:
TextBlock text = new TextBlock();
// Some code to define text, font, etc. here
// Turn if Orientation is vertical
if (Orientation == Orientation.Vertical)
{
text.RenderTransform = new RotateTransform() { Angle = 270 };
}
// Update, then ActualWidth is set correctly
text.UpdateLayout();
// Position of label centered to given position
double halfWidth = text.ActualWidth / 2;
double x1 = (Orientation == Orientation.Horizontal) ? x - halfWidth : x;
double y1 = (Orientation == Orientation.Horizontal) ? y : y + halfWidth;
Canvas.SetLeft(text, x1);
Canvas.SetTop(text, y1);
Children.Add(text); // Add to Canvas
This works actual fine, but is it possible to do this without UpdateLayout
. If I remove UpdateLayout
, then I do not get the position I am looking for, because ActualWidth is (of course) zero.
You might be able to do that by binding the Canvas.Top
/Canvas.Left
values to the TextBlock's ActualWidth
/ActualHeight
and using a Converter
.
Here's an example. I'm using a custom MathConverter
that I usually use for mathematical formulas (code can be found here), but you could also use a plain converter that returns half of whatever value it gets passed.
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="Canvas.Left"
Value="{Binding RelativeSource={RelativeSource Self},
Path=ActualWidth,
Converter={StaticResource MathConverter},
ConverterParameter=@VALUE/2}" />
</Trigger>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="Canvas.Top"
Value="{Binding RelativeSource={RelativeSource Self},
Path=ActualHeight,
Converter={StaticResource MathConverter},
ConverterParameter=@VALUE/2}" />
</Trigger>
</Style.Triggers>
</Style>
Edit
Just re-read the question and realized you're trying to center the TextBlock at a specific x,y coordinate on the Canvas. In that case, you'll need to implement a MultiConverter
instead of a regular Converter
so that you can pass it two parameters: the X/Y value, and the ActualHeight/ActualWidth value
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With