Question

I am trying to get the position of user control via TransformToVisual method using this line of code:

this.TransformToVisual(ParentElement).Transform(new Point());

If the control is defined in XAML, coordinates are all right. But now I want to define controls dynamicaly like this:

stackPanel.Children.Add(new Control());

The coordinates are shifted and the TransformToVisual method is ignoring margins and aligns (returns top-left corner of stackpanel).

The XAML hierarchy is following:

<Grid x:Name="ParentElement">
    <StackPanel>
        <StackPanel>
            <Border>
                <StackPanel>
                    <TextBlock  />
                    <StackPanel x:Name="stackPanel" />
                </StackPanel>
            </Border>
        </StackPanel>
    </StackPanel>
</Grid>

So my question is: is there any way to get the coordinates properly again?

Thanks, kwitee

Was it helpful?

Solution

I was able to fix the issue myself:

If I call UpdateLayout() method before calling TransformToVisual(), coordinates are no longer bad. There was some other minor issue with ActualWidth and height properties, which were returned as zeros. I fixed that by calling these properties in Dispatcher.BeginInvoke delegate.

OTHER TIPS

I wanted to add something to this as I ran into a very similar problem that caused problems for me for a while. When I accessed the Dispatcher on a UIElement in WinRT for Windows 8.1 I was not able to find a BeginInvoke method so I wasn't able to attempt the solution that you have listed.

After some testing though I think that the root cause of my issue was changing the layout of the UI and then calling TransformToVisual before the system had time to update the layout properly. This is likely the same issue that you mentioned above. I found that running TransformToVisual on pieces of the UI that were not having their layout affected returned the proper results, it was only for pieces of the UI that layout was being updated where the problem existed.

It seems like when the layout is changed in order for TransformToVisual to work properly the UI has to have a chance to 'react' to the layout update. In my case I was changing the layout and then immediately after calling TransformToVisual (one line right after the other both within a Tapped event handler). Since these calls were both in the same method the UI probably wasn't able to process any new messages between when the layout was updated and TransformToVisual was called (I am assuming that the layout update gets pushed as a message on the UI processing loop). If I moved TransformToVisual into the MouseUp event (I was using a mouse at the time) then everything worked fine. Probably calling BeginInvoke in your case did much the same thing where it 'pushed' the new work to be done which caused any waiting work in the queue (the layout update) to be processed first.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top