How to get a static reference to a WPF Window?

后端 未结 4 1385
醉酒成梦
醉酒成梦 2021-01-12 05:39

I\'ve tried a huge amount of ways to get a static reference of my window across my program. I need to access all of its members at runtime from different classes, so a stati

4条回答
  •  时光说笑
    2021-01-12 06:16

    It is absolutely possible to instantiate your own windows with WPF. But yes, you would have to be on the "UI thread" (which is a STA thread).

    For example, say that we would like to have a property on our App class that exposes some window.

        public partial class App
        {
            private static Window _myWindow;
    
            public static Window1 MyWindow
            {
                get
                {
                    if (_myWindow == null)
                        _myWindow = new Window1();
                    return _myWindow;
                }
           }
        }
    

    The problem with this code is, as you have experienced, depending on what thread is calling the MyWindow getter, new Window1() will fail if the thread is not an STA.

    To make sure the window is created on the right thread, enter the Dispatcher object. This object is used throughout WPF to make sure that communication between UI elements is done on the correct thread.

    Back to our new Window1, we can use the App.Dispatcher object to make sure the new operation is done on the main application thread, like this:

            public static Window1 MyWindow
            {
                get
                {
                    if (_myWindow == null)
                    {
                         var window = 
                                 Application.Current.Dispatcher.Invoke(
                                   new Func(() => new Window1()));
    
                        _myWindow = (Window1)window;
                    }
    
                    return _myWindow;
                }
           }
    

    Here, I get a hold on the current application's Dispatcher object and calls Invoke with a delegate that does the actual newing. Invoke ensures that my delegate is executed on the correct thread, and returns the result. Voila, the window is created without the dreaded STA error.

    Now, what you must have in mind is that further calls made on the MyWindow instance must also be made on the correct thread. To avoid littering your code with calls to Dispatcher.Invoke, it could be useful to wrap the window instance behind a simple API. E.g. a Show method could be implemented like this, making sure to marshal the Show call via the Dispatcher object of the window:

            public static void ShowMyWindow()
            {
                MyWindow.Dispatcher.Invoke(new Action(MyWindow.Show));
            }
    

提交回复
热议问题