Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I center a TextBlock to a given position

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.

like image 224
Em1 Avatar asked Sep 12 '11 15:09

Em1


1 Answers

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

like image 124
Rachel Avatar answered Oct 06 '22 01:10

Rachel