Stefan Chonov
Stefan Chonov

Reputation: 121

How can I grant focus to a created window instead of creating a new instance?

I found so many topics about how to prevent multiple instances of Windows.Forms but I still can't find how to prevent multiple instances for WPF windows. I'll explain my idea. I have a WPF Window. This window have a beautiful custom button. When the button is clicked it opens new window. My problem is that when I click multiple times on the same button the same window appears as many times I clicked the button. How to prevent this? Is it possible instead a new window is opened simply the already opened one to take the focus?

Upvotes: 1

Views: 450

Answers (3)

RvdK
RvdK

Reputation: 19800

Well you have to check if it is created before creating a new one:

Pseudo like code (only have notepad here)

private YourWindow wnd = null;

void OnButton_Click()
{
    if (wnd == null) wnd = new YourWindow();
    wnd.Show();
}

Upvotes: 2

Matthew Walton
Matthew Walton

Reputation: 9979

I tend to use two approaches. Sometimes, I do as PowerRoy suggests and I store a field in a suitably central place in the application which has a reference to the window. If that field isn't null, I activate it instead of creating a new instance.

Sometimes when there are many types of windows but I only want one of each, I use a list of a common base class (List perhaps). Each created window is put in there, and whenever I want to create or switch to one of them, I filter it by type and check if there's anything there and switch to it if there is. Something like:

List<Window> allWindows = new List<Window>();

// ... elsewhere I want to create a ShinyWindow
void ActivateShinyWindow()
{
    var shiny = allWindows.OfType<ShinyWindow>().FirstOrDefault();
    if (shiny == null)
    {
        shiny = new ShinyWindow();
        allWindows.Add(shiny);
    }
    ActivateWindow(shiny);
}

Where ActivateWindow() does whatever is necessary to make it visible and bring it to the front or whatever. Actually the biggest thing I've got doing this is inside a tabbed interface, so it's all run by the enclosing shell window.

This is a bit like Kevin Ross' answer, except I'm indexing the collection by type. It obviously doesn't work if you ever want multiple windows which are instances of the same class, and then you're going to want something more like what Kevin did. My strongly-typed functional-programming background says I'd rather use a nice enum to index the windows than a string though.

Upvotes: 1

Kevin Ross
Kevin Ross

Reputation: 7215

I have seen a few methods and this is the one I use. Its in VB but you should be able to convert it to C#. There might well be better ways but I'm no WPF expert!

I have a function tucked away in a module that looks like this

 Public Class FormsCollection
        Public Shared Forms As ArrayList = New ArrayList
    End Class

    Public Function Find_form(strForm_name As String)
        For Each F In FormsCollection.Forms
            If F.ToString = strForm_name Then
                Find_form = F
                Exit Function
            End If
        Next
        Find_form = Nothing
    End Function

Then when I’m trying to open a form the code looks like this

Dim FormToOpen As FormToOpen
            If IsNothing(Find_form("FormToOpen")) Then
                FormToOpen = New FormToOpen
            Else
                FormToOpen = Find_form("FormToOpen ")
            End If
            With FormToOpen
                .Owner = Me
                .ShowDialog()
            .Activate
                        End with

Upvotes: 1

Related Questions