如何将焦点授予创建的窗口而不是创建新实例?

时间:2012-01-09 08:15:20

标签: c# wpf

我发现了很多关于如何防止Windows.Forms实例的主题,但我仍然无法找到如何防止WPF窗口的多个实例。我会解释我的想法。我有一个WPF窗口。这个窗口有一个漂亮的自定义按钮。单击该按钮时,将打开新窗口。我的问题是,当我在同一个按钮上多次单击时,同样的窗口会出现多次我点击按钮。怎么预防这个?是否有可能只打开一个新窗口,只是已经打开的窗口可以关注焦点?

3 个答案:

答案 0 :(得分:2)

你必须在创建新的之前检查它是否已创建:

类似伪代码(这里只有记事本)

private YourWindow wnd = null;

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

答案 1 :(得分:1)

我见过几种方法,这就是我使用的方法。它在VB中,但你应该能够将它转换为C#。可能有更好的方法,但我不是WPF专家!

我的功能隐藏在一个看起来像这个

的模块中
 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

然后,当我尝试打开表单时,代码看起来像这样

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

答案 2 :(得分:1)

我倾向于使用两种方法。有时候,我按照PowerRoy的建议进行操作,并将字段存储在应用程序的适当中心位置,该位置具有对窗口的引用。如果该字段不为null,则激活它而不是创建新实例。

有时当窗口类型很多但我只想要其中一个时,我会使用一个公共基类列表(也许是List)。每个创建的窗口都放在那里,每当我想创建或切换到其中一个时,我按类型过滤它并检查是否有任何东西并切换到它(如果有)。类似的东西:

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

ActivateWindow()执行任何必要的操作以使其可见并将其置于前面或其他任何位置。实际上,我做过的最重要的事情就是在一个标签界面中,所以它都是由封闭的shell窗口运行。

这有点像凯文罗斯的答案,除了我按类型索引集合。如果你想要多个同一类实例的窗口,那么它显然不起作用,然后你会想要更像Kevin所做的事情。我的强类型函数编程背景说我宁愿使用一个很好的枚举来索引窗口而不是字符串。