Как центрировать TextBlock в заданной позиции? - PullRequest
7 голосов
/ 12 сентября 2011

TextBlock должен быть центрирован по позиции x (или y, если ориентация вертикальная).Я реализовал:

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

Это отлично работает, но возможно ли это сделать без UpdateLayout.Если я удаляю UpdateLayout, то я не получаю искомую позицию, потому что ActualWidth (конечно) равен нулю.

Ответы [ 2 ]

3 голосов
/ 12 сентября 2011

Вы можете сделать это, связав значения Canvas.Top / Canvas.Left с ActualWidth / ActualHeight TextBlock и используя Converter.

Вот пример. Я использую пользовательский MathConverter, который я обычно использую для математических формул (код можно найти здесь ), но вы также можете использовать простой преобразователь, который возвращает половину любого значения, которое он получил.

<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>

Редактировать

Просто перечитайте вопрос и обнаружите, что вы пытаетесь центрировать TextBlock в определенной координате x, y на Canvas. В этом случае вам нужно реализовать MultiConverter вместо обычного Converter, чтобы можно было передать ему два параметра: значение X / Y и значение ActualHeight / ActualWidth

0 голосов
/ 12 сентября 2011

Я предполагаю, что вы написали этот код в конструкторе.Это было бы причиной, почему ActualWidth не имеет значения. Весь код не был протестирован (нет IDE).Это необходимо сделать после Loaded Event, после того как WPF построит макет.Это перенаправленное событие, кстати.

public class Class1{
public Class1 ()
{
    this.Loaded += (sender, args) =>
    {
        TextBlock text = new TextBlock();

        if (Orientation == Orientation.Vertical) 
        {
          text.RenderTransform = new RotateTransform() { Angle = 270 };
        }

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

Этот код, вероятно, будет работать.Конечно, как я читаю ваш код, кажется, что этот код находится в конструкторе класса, который вы создали из Canvas.Обычно в этом нет необходимости, кроме случаев, когда вам действительно необходимо расширить основные функции элемента управления canvas.Вы можете создавать повторно используемые компоненты поверх существующих элементов управления, создавая UserControl.Вы должны особенно использовать этот подход, если вам не нужно переопределять какой-либо метод Canvas.

В качестве альтернативы, если вы просто хотите поместить центрируемый предмет внутри контейнера, следующий xaml прекрасно с этим справится:

     <Grid>
        <TextBlock Text="Haha!" VerticalAlignment="Center" HorizontalAlignment="Center"/>
     </Grid>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...