Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF - Getting position of a control keeps returning {0;0}

Tags:

c#

position

wpf

I'm trying to get the positions of controls (buttons) but it keeps returning {0;0}. I'm sure there's an explanation for this, but I can't figure out why this happens.

I want the position of the control, relative to the window or a certain container. My buttons are arranged in another grid. Taking the margins of these buttons would just give 0,0 since they're all inside grid cells.

What I tried:

- var point = btnTest.TransformToAncestor(mainGrid).Transform(new Point());
- UIElement container = VisualTreeHelper.GetParent(btnTest) as UIElement;
  Point relativeLocation = btnTest.TranslatePoint(new Point(0, 0), mainGrid);

I tried this with a grid as a parent and with a canvas. Everything I try gives me {0,0}. When I change the new Point parameters, the position does change. It stays the same as the parameters.

Small part of my XAML:

    <Grid x:Name="mainGrid">
    <Grid Name="buttonGrid" Margin="105,64,98.4,97.8">
        <Grid.RowDefinitions>
            <RowDefinition Height="25"/>
            <RowDefinition Height="25"/>
            <RowDefinition Height="25"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="50"/>
            <ColumnDefinition Width="50"/>
            <ColumnDefinition Width="50"/>
        </Grid.ColumnDefinitions>
        <Button x:Name="btnTest" Grid.Row="0" Grid.Column="0" Content="Button" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="26" Height="29"/>
        <Button x:Name="btnTest2" Grid.Row="1" Grid.Column="1" Content="Button" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="26" Height="29"/>
    </Grid>
</Grid>
like image 728
Thomas van Schijndel Avatar asked Jun 04 '18 08:06

Thomas van Schijndel


1 Answers

Your code works perfectly fine, it is the timing that is the issue. The UI elements must be drawn before the position can be retrieved.

The code sample below shows the point extraction running in the constructor with the result 0,0 and then running in the loaded event which returns the desired result 84,78.

<Window x:Class="WpfApp7.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
<Grid x:Name="mainGrid">
    <Button x:Name="btnTest" Content="TileButton" HorizontalAlignment="Left" Margin="84,78,0,0" VerticalAlignment="Top" Width="109" Height="103"/>
</Grid>

 public MainWindow()
    {
        InitializeComponent();
        GetPoint();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        GetPoint();
    }

    private void GetPoint()
    {
        var point = btnTest.TransformToAncestor(mainGrid).Transform(new Point());
        UIElement container = VisualTreeHelper.GetParent(btnTest) as UIElement;
        Point relativeLocation = btnTest.TranslatePoint(new Point(0, 0), mainGrid);
        MessageBox.Show($"X = {relativeLocation.X} Y = {relativeLocation.Y}");
    }        
like image 191
Matt Norrie Avatar answered Nov 14 '22 23:11

Matt Norrie