none
How to get the position of a control in silverlight?

    Question

  •  Hi,

    Is there a way to get the position (left, top) of a UIElement?

    I know a control has ActualWidth and ActualHeight property. But I did not see any Position property. I'm not using Canvas so I cannot use Canvas.Left/Canvas.Top either. I need to get the absolute position of a control(say a border) at runtime so I can position some HTML element on top of my silverlight control.

     

     

     

    Wednesday, March 19, 2008 9:09 PM

Answers

  • Here's a code snippet that will get the Top/Left coordinates of the element within the application.
    Replace "this" with the object you want to find the position of.

    GeneralTransform gt = this.TransformToVisual(Application.Current.RootVisual as UIElement);
    Point offset = gt.Transform(new Point(0, 0));
    double controlTop = offset.Y;
    double controlLeft = offset.X;

    Wednesday, March 19, 2008 9:23 PM

All replies

  • Here's a code snippet that will get the Top/Left coordinates of the element within the application.
    Replace "this" with the object you want to find the position of.

    GeneralTransform gt = this.TransformToVisual(Application.Current.RootVisual as UIElement);
    Point offset = gt.Transform(new Point(0, 0));
    double controlTop = offset.Y;
    double controlLeft = offset.X;

    Wednesday, March 19, 2008 9:23 PM
  • crpietschmann,

    Thank you so much! It works.

    Wednesday, March 19, 2008 9:35 PM
  •   This however doesn't work with object that have had a Transform applied to them. For example, if a RotateTransform has been applied to it, the top/left point returned will actually be in the bottom/right possition. Is there any way to find the position that takes into account the transform?

    Wednesday, December 10, 2008 1:13 PM
  •  Man that is harsh. Why cant there be a ActualPosition property or something.

    Friday, May 29, 2009 1:10 PM
  • I know, I wish there were a simpler way.  Here's how to obtain the four points of an element regardless if there has been a transform applied to it:

    // Obtain transform information based off root element
    GeneralTransform gt = element.TransformToVisual(Application.Current.RootVisual);

    // Find the four corners of the element
    Point topLeft = gt.Transform(new Point(0, 0));
    Point topRight = gt.Transform(new Point(element.RenderSize.Width, 0));
    Point bottomLeft = gt.Transform(new Point(0, element.RenderSize.Height));
    Point bottomRight = gt.Transform(new Point(element.RenderSize.Width, element.RenderSize.Height));
      

     

    Friday, May 29, 2009 1:27 PM
  • Hello,

    It does not work for my button. I got this error "Value does not fall within the expected range.".

    Any idea?

    XAML

    <UserControl

    xmlns:control="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"

    xmlns:template="clr-namespace:System.Windows;assembly=System.Windows.Controls"

    xmlns:layoutToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Layout.Toolkit" xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="SilverlightApplication1.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    xmlns:cal="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation"

    xmlns:myctl="clr-namespace:SilverlightClassLibrary1;assembly=SilverlightClassLibrary1"

    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

    <UserControl.Resources>

    <DataTemplate x:Key="cellTemplate">

    <Button Content="Button" cal:Click.Command="{Binding ElementName=LayoutRoot,Path=DataContext.SaveCommand}"/>

    </DataTemplate>

    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">

    <StackPanel>

    <data:DataGrid x:Name="dg" AutoGenerateColumns="False" ItemsSource="{Binding Source}" >

    <data:DataGrid.Columns>

    <data:DataGridTextColumn Header="Name"

    Binding="{Binding Name}" />

    <data:DataGridTemplateColumn Header="Text"

    CellTemplate="{StaticResource cellTemplate}"

    />

    </data:DataGrid.Columns>

    </data:DataGrid>

    <Button x:Name="saveButton" Content="Click" cal:Click.Command="{Binding ElementName=LayoutRoot,Path=DataContext.SaveCommand}"

    KeyDown="Button_KeyDown"/>

    </StackPanel>

    </Grid>

    </UserControl>

    C#

    public MainPage() {this.DataContext = this;

    InitializeComponent();

     

    GeneralTransform gt = saveButton.TransformToVisual(Application.Current.RootVisual);

    Point offset = gt.Transform(new Point(0, 0));

    double controlTop = offset.Y;

    double controlLeft = offset.X;

    // Find the four corners of the element

    Point topLeft = gt.Transform(new Point(0, 0));

    Point topRight = gt.Transform(new Point(saveButton.RenderSize.Width, 0));

    Point bottomLeft = gt.Transform(new Point(0, saveButton.RenderSize.Height));Point bottomRight = gt.Transform(new Point(saveButton.RenderSize.Width, saveButton.RenderSize.Height));

    }

    I'm getting this error "Value does not fall within the expected range."

    Monday, September 21, 2009 1:07 AM
  •  If you need to get a control's position, you need to wait until the page is loaded. Move your code to the Loaded event handler:

    public MainPage()
            {
                this.DataContext = this;

                InitializeComponent();
                this.Loaded += new RoutedEventHandler(MainPage_Loaded);

    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
            {
                GeneralTransform gt = saveButton.TransformToVisual(Application.Current.RootVisual);


                  ...

           }

    Tuesday, September 22, 2009 7:11 AM
  • ... And how can I set the position of a UIElement?

    Tuesday, May 18, 2010 3:57 AM
  • ... And how can I set the position of a UIElement?

     

    If you want to position a control in absolute position, use Canvas as your Layout panel. Set Canvas.Left/Canvas.Right to the control to position it in the Canvas.

     

    Wednesday, May 19, 2010 12:44 PM
  • Thanks for the answer,

    I would like to have an additional information:

    when do these coordinates get updated?

    I am trying to get coordinates of treeview elements and I would like to update them after moving or changing order of tree nodes.

    I tried to calculate them after arrangeoverride but there I get old node coordinates (coordinates before the move)

    I think I have to attach to some kind of drawing event, after elements are actually rendered...

    Do you have any suggestion?

    Many thans in advance,

    Paolo

    Friday, July 16, 2010 6:44 AM
  • Hi. I have the same problem. I have an simple XAML file with LayoutRoot and got the error

    • Der Wert liegt außerhalb des erwarteten Bereichs. (German)

    By using:

    Me.LayoutRoot.TransformToVisual(Application.Current.RootVisual)


    Please, if any one has fixed this with Silverlight 4, please share with us.

    Friday, September 10, 2010 5:08 AM