I assume that you wrote this code in the constructor. That would be the reason why ActualWidth doesn't matter. All code has not been tested (there is no IDE). You need to do this after the loaded event, after WPF has built the layout. This is a routable event, by the way.
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); }; }
This code is likely to work. Of course, as I read your code, this code seems to be in the constructor from the class that you got from Canvas. Generally, there is no need to do this, unless you really need to extend the basic functions of the canvas control. You can make reusable components on top of existing controls by creating a UserControl. This approach is especially recommended if you do not need to override any Canvas method.
Alternatively, if you just want to have a centered element inside the container, the following xaml will do it just fine:
<Grid> <TextBlock Text="Haha!" VerticalAlignment="Center" HorizontalAlignment="Center"/> </Grid>
Alex maker
source share