How to get a static link to a WPF window?

I tried a huge number of ways to get the static link of my window in my program. I need to access all my members at runtime from different classes, so a static link is needed.

What I would like to have is something like Program.Window1 , where Core is static and MyWindow is one of its static members.

In WinForms, I usually declare my static form in Program.cs, but this does not seem to work with WPF and their usual "App.xaml" ApplicationDefinition.

How can i do this?

Note. I have already tried several ways: using a direct call in a new window (i.e. Program.Window1 = new Window1() ) will not work, since I get a thread invalidation exception. As far as I understand so far, only ApplicationDefinitions applications can run windows in WPF.

Here is the exception when I try to create a window "by code" rather than the default XAML ApplicationDefinition StartupUri:

The calling thread must be an STA because it requires many user interface components.

+7
reference c # static wpf window
source share
4 answers

Create a static class that can contain the window object, and then when the window is created, pass it to the static class, and then the static class can pass the window object to interested parties, even if the window the object itself is not static. Something like that. There is no need for your form to be static, you just need a static place to store the form object.

 public class Core { internal static MyWindowClass m_Wnd = null; // call this when your non-static form is created // public static void SetWnd(MyWindowClass wnd) { m_Wnd = wnd; } public static MyWindow { get { return m_Wnd; } } } 
+10
source share

Try this ((MainWindow) App.Current.Windows [0]). MainCanvas.

+5
source share

You can absolutely create your own windows using WPF. But yes, you must be in a "UI stream" (which is an STA stream).

For example, let's say that we would like to have a property in our App class that provides some kind of 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, as you already found out, depending on which thread is causing the HTTP request, is disabled if the thread is not an STA.

To ensure that the window is created in the desired stream, enter a Dispatcher object . This object is used throughout WPF to ensure that communication between user interface elements is done in the correct thread.

Back to our new Window1 , we can use the App.Dispatcher object to make sure that the new operation is performed in the main thread of the application, for example:

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

Here I get hold of the current Dispatcher object of the application and invokes Invoke using a delegate that does the actual novelty. Invoke guarantees that my delegate will be executed in the correct thread and will return the result. Voila, a window is created without a terrible STA error.

You should now bear in mind that further calls made to the MyWindow instance must also be made in the correct thread. To avoid clogging up your code with calls to Dispatcher.Invoke, it would be useful to wrap the window instance with a simple API. For example. The Show method can be implemented as follows: make sure that the marshal of calling Show is through the window's Dispatcher object:

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

I have used this with success. Declare a static window type variable. Then, in the window constructor, set the static variable to "this". I used it throughout the application and it seems to work fine from static or instance methods.

  public static MainWindow screenMain = null; public MainWindow() { InitializeComponent(); screenMain = this; //static reference to this. } 

For example, I can do this.

  private delegate void del(); .... screenMain.Dispatcher.Invoke(new del(delegate() { screenMain.ButtonSubmit.IsEnabled = true; screenMain.ButtonPreClearing.IsEnabled = true; })); 
+2
source share

All Articles