views:

210

answers:

4

I have a WPF window that I am launching from inside of a winform app. I only want to allow once instance of that WPF window to be open at a time, and not warn that user if they try to open it again.

I am having a problem however trying to search for that WPF window being open because the window is being launched from a winform. What I normaly do is when searching for a winform, I search for any instances of that winform existing in the Application.Current.OpenForms, and when in WPF I search for Application.Current.Windows

The problem I have is that System.Windows.Application.Current is null when launched from inside of a winform, so I can't search for the WPF window that way. Is there any better way of searching for an existing instance of an open window?

My Code:

if (System.Windows.Application.Current != null)
                {
                    foreach (System.Windows.Window win in System.Windows.Application.Current.Windows)
                    {
                        if (win is frmCaseWpf)
                        {
                            MessageBox.Show("You may have only one active case open at a time.", "Open Case",
                                      MessageBoxButtons.OK,
                                      MessageBoxIcon.Stop);

                            win.WindowState = System.Windows.WindowState.Normal;
                            win.Focus();
                            win.Activate();
                            return;
                        }
                    }
                }
A: 

It would be better make the frmCaseWpf class a singleton. That way you can't create another instance

Thomas Levesque
A: 

Instead of searching the static application objects, you could instead just track this within your window, with a single static variable. Just keep a variable in the window:

private static frmCaseWpf openWindow = null; // Assuming your class name is frmCaseWpf

When you create a window, either in the initialize routines, or OnLoaded, depending on how you want it to work..:

partial class frmCaseWpf {
    public frmCaseWpf {
         this.OnLoaded += frmCaseWpf_OnLoaded;
    }

    private void frmCaseWpf_OnLoaded(object sender, RoutedEventArgs e)
    {
         if (this.openWindow != null)
         {
              // Show message box, active this.openWindow, close this
         }
         this.openWindow = this;
    }
}

If you want this window to be reusable, make sure to set this.openWindow = null; when you close the window, as well.

Reed Copsey
A: 

Rather than try to search for a Window instance, many people use a session- (or system-) wide "Mutex" or a Mutual Exclusion lock. I was going to rewrite one for you, but I found a good codeproject article demonstrating the technique. It's not complex and very simple.

http://www.codeproject.com/KB/cs/SingleInstanceAppMutex.aspx?msg=2908697

Sneak peek:

[STAThread]
static void Main()
{
    bool onlyInstance = false;
    Mutex mutex = new Mutex(true, "UniqueApplicationName", out onlyInstance);
    if (!onlyInstance) {
     return;
    }
    Application.Run(new MainForm);
    GC.KeepAlive(mutex);
}

Hope this helps.

(edit: of course you'll have to modify this slightly for your particular use-case, but it demos the general idea)

x0n
This is not what Russ was asking... he's not trying to make a single instance application, he just wants a specific window of the application to be displayed only once
Thomas Levesque
urgh, right. I misread that. how hard is that? track it with a static flag... sheesh.
x0n
@x0n- That’s why I choose the answer I choose, because tracking it with a static flag solved my problem. It was hard because I had never done it that way, and everyone else on my team was laid off quite a while ago, so there aren’t too many others to bounce problems off anymore.I also don't see a lot of information on the net about interop between winforms and wpf, which I am pretty heavy into with this particular application.
Russ
A: 

I am not really a 'proper' programmer, however I have achieved this in a WPF application (not from a winforms one) by using the following:

Dim wdwDetails As New detailsNew()
Private Sub openNewDetails(ByVal recordID As String)
 wdwDetails.Owner = Me
 wdwDetails.recordID = recordID
 wdwDetails.WindowStartupLocation = Windows.WindowStartupLocation.CenterOwner
 wdwDetails.Show()
End Sub

Essentially because I am creating the window object outside of the sub that opens it, there will only be a single window. Any new call to the window open sub will use the same object. But I guess that is what Thomas is referring to also.

Like I said, not sure if this will help you or not though.

TravisPUK
Obviously mine is also VB not C#. :)
TravisPUK