Russ
Russ

Reputation: 12540

How can I make sure only one WPF Window is open at a time?

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;
                        }
                    }
                }

Upvotes: 3

Views: 18406

Answers (6)

Benicio
Benicio

Reputation: 1

You can use XXXwindown.isLoad to check if window is loaded before you create a new window:

if ( !ChildWindow.IsLoaded)
{
   childWindow= new ChildWindow();
   childWindow.Show();
}

Upvotes: 0

Brian Rizo
Brian Rizo

Reputation: 858

Here's something that's working for me.

    private About aboutWin;
    private void AboutOpenClicked(object sender, RoutedEventArgs e)
    {
       if(aboutWin == null)
       {
           aboutWin = new About();
           aboutWin.Closed += (a, b) => aboutWin = null;
           aboutWin.Show();
       }
       else
       {

           aboutWin.Show();  
       }

    }

Upvotes: 4

user57630
user57630

Reputation:

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.

Upvotes: 0

x0n
x0n

Reputation: 52480

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)

Upvotes: 0

Reed Copsey
Reed Copsey

Reputation: 564851

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.

Upvotes: 8

Thomas Levesque
Thomas Levesque

Reputation: 292695

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

Upvotes: 0

Related Questions