0

Possible Duplicate:
Notification when WPF UI closes

I have asked a very similar question before, but i did not get any usable response. I am hoping that someone out there might be able to help me.

I have an existing tray app programmed as a Windows Form app. I have an existing Settings form programmed as WPF.

The Tray App needs to be able to: * Open the Settings App n times, with only one instance ever opened at a time * Receive notification when the user closes the Settings App.

The Settings App uses a ResourceDictionary, which I believe means it must be started from App.xaml.

I can get the Settings window to open once and notify the Tray when it is shut down using the following code, but I cannot get it to open again.

        if (gui == null)
        {
            //shell = new mainWindow();
            //shell.CloseEvent += settings_FormClosed;

            gui = new App();
            //gui.ShutdownMode = ShutdownMode.OnExplicitShutdown;
            gui.MainWindow = shell;
            gui.InitializeComponent();
            //gui.Run();
            gui.Exit += new System.Windows.ExitEventHandler(settings_FormClosed);

            IsUIOpen = true;
        }

If I uncomment the lines above, I can then intercept the close event, and set the Visibility to Hidden. The next time the user selects Settings, I can set it back to Visible. However, the first time Settings opens, it will not trigger the Exit event and shell is not getting all the ReferenceDictionary (or losing access to it), so the window is not displaying properly.

Is there a way to run WPF from the app, and access MainWindow (which often seems to be null, and is not of the type of my own window) so a custom listener can be added to mainWindow?

Alternately, is there a way to dispose of the static App so I can re-instantiate it the next time the user clicks on Settings.

I know there must be some way to get WPF to play nice with Win Forms. Thank you to everyone who attempts to help. This has been giving me major headaches.

Community
  • 1
  • 1
Tim
  • 2,731
  • 9
  • 35
  • 72

1 Answers1

1

Since your settings is an app, I would use the System.Diagnostics.Process from within your Winforms app to start your WPF settings app. Since you are starting the Settings as an application rather than trying to invoke it as a Window, your styles will be loaded. Also, you can use the WaitForExit() or WaitForExit(int) methods of Process to wait for your settings app to finish, relinquishing control back to your Winforms app only when the Settings app is complete. This also serves as the notification requested when the Settings app is closed.

Here's a quick code snippit:

IN EVENT THAT OPENS SETTINGS WPF APP:

Process myProcess = new Process();
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.FileName = "C:\\mysettingsapp\\mysettingsapp.exe"; // replace with path to your settings app
myProcess.StartInfo.CreateNoWindow = false;
myProcess.Start();
// the process is started, now wait for it to finish
myProcess.WaitForExit();  // use WaitForExit(int) to establish a timeout

By calling WaitForExit on the main thread, the WinForms app is blocked waiting for the settings app to complete. This will prevent users from opening more than one settings window. I didn't see a non-blocking requirement for the Winforms app. So if you can't block, I can come up with another way.

UPDATE To grab the executing assembly's path:

  string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase );
Josh
  • 2,955
  • 1
  • 19
  • 28
  • Thank you; this was a brilliant answer. I don't want the code to block, but I can add this to a separate thread to take care of that. I have but one question: Is there a way to do this without giving an absolute path? The WPF is a project in my solution; is there a way to reference that instead? Again, thank you so much for your response. This has been haunting me for days! – Tim Oct 04 '12 at 20:09
  • I believe you have to provide a full path, but if it's part of the solution, you could the Assembly object to get the executing path and build from there to your Settings app. I updated my answer above to show it formatted. – Josh Oct 04 '12 at 20:18
  • You are awesome. I wish I could bump your answer up more than one. Thank you so much! – Tim Oct 04 '12 at 20:56
  • @Tim: Just FYI, if you want to raise the profile of your question to get more help, just edit your question to add more information, clarifications etc. This moves it to the top of the Active Questions list, so there's no need to post a new question similar to the first. – Surfbutler Oct 05 '12 at 08:37
  • @Surfbutler Thank you, I did not realize that. I will not repost the question in the future. Thanks for the info. – Tim Oct 05 '12 at 15:53