简体   繁体   English

TransformToAncestor并不总是有效

[英]TransformToAncestor doesn't always work

I'm currently working on my first WPF app. 我目前正在开发我的第一个WPF应用程序。 I'm getting data from some XML file and based on that file I populate stackpanel with some dynamically created buttons. 我从一些XML文件中获取数据,并基于该文件用一些动态创建的按钮填充stackpanel。

later on I need to retrieve X coordinate from specific button for which i use method: 稍后,我需要从我使用方法的特定按钮中检索X坐标:

private double GetStationCoordinates(int stationIdx)
    {
        foreach (Button station in StationMap.Children)
        {
            if (stationIdx != Convert.ToInt16(station.Tag)) continue;
            var relativePoint = station.TransformToAncestor(Application.Current.MainWindow).Transform(new Point(0, 0));
            //Console.WriteLine(stationIdx + " " + relativePoint.ToString());
            return relativePoint.X;
        }
        return 0;
    }

And then I use this coordinates to paint some points in other panel under the buttons. 然后,我使用此坐标在按钮下的其他面板中绘制一些点。 It all worked fine until I set my main window property 一切正常,直到我设置主窗口属性

SizeToContent="WidthAndHeight"

Now - when I paint my points for the first time after launching the app (and after I populate StackPanel with buttons) they all (points) receive the same X coordinate - 11. When i hit Refresh button everything is ok.But the first paint - just after adding buttons is problematic. 现在-当我在启动应用程序后第一次绘制我的点(并且在我用按钮填充StackPanel之后)时,它们所有(点)都收到相同的X坐标-11。当我按下“刷新”按钮时,一切正常。 -仅在添加按钮后出现问题。 Same problem occurs when I reload buttons configuration xml file. 当我重新加载按钮配置xml文件时,会发生相同的问题。 I'm starting with clearing all the Children in StackPanel and populating it with new ones. 我首先要清除StackPanel中的所有子级,然后用新的子级填充它。 After that first painting of points is broken - GetStationCoordinates returns 11 for every button. 在第一次绘制点中断后,GetStationCoordinates为每个按钮返回11。 Is it somehow connected to autosize property of main window? 它以某种方式连接到主窗口的autosize属性吗?

You're probably trying to get the position of elements that haven't been correctly positioned yet. 您可能正在尝试获取尚未正确定位的元素的位置。 Defer that code until the view has loaded, using any of these two approaches: 使用以下两种方法中的任何一种,将代码推迟到视图加载之前:

a) Subscribe to the Loaded event of the view and do it there. a)订阅视图的Loaded事件并在那里进行。

private void Window_Loaded(object sender, EventArgs e)
{
    this.Loaded -= Window_Loaded;  // Or else it could get called again later

    int id;
    // do stuff

    GetStationCoordinates(id);
}

b) Put it in an asynchronous call with Dispatcher.BeginInvoke b)使用Dispatcher.BeginInvoke将其放入异步调用中

private void SomeCode()
{
    int id;
    // do other stuff

    Dispatcher.BeginInvoke(new Action(() =>
        {
            GetStationCoordinates(id);
        }),
        DispatcherPriority.Loaded);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM