2009-08-26 99 views
3

我有一个WPF窗口,我从一个winform应用程序内启动。我只想让该WPF窗口的实例一次打开,并且不会在该用户尝试再次打开时警告该用户。如何确保一次只打开一个WPF窗口?

不过,我有试图寻找该WPF窗口是否打开,因为正在从一个winform推出了窗口的问题。对于一个winform搜索时我normaly做的是,我要寻找的那个的winform现有的Application.Current.OpenForms的任何实例,当在WPF我搜索Application.Current.Windows

我的问题是,从内部启动时System.Windows.Application.Current为null一个winform,所以我不能以这种方式搜索WPF窗口。有没有更好的方法来搜索打开窗口的现有实例?

我的代码:

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

回答

4

而不是搜索静态应用程序对象,而是可以只在一个静态变量在窗口中跟踪这个。只要保持一个变量在窗口:

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

当你创建一个窗口,无论是在初始化程序,或装载的,这取决于你想如何它的工作..:

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

如果您希望这个窗口是可重用的,确保设置this.openWindow = null;当你关闭窗户时,也是如此。

+0

我使用.NET 4.5和'this.OpenWindow'不存在。有其他选择吗? – valsidalv 2013-11-20 04:16:13

0

倒不如让frmCaseWpf类singleton。这样,你不能创建另一个实例

0

,而不是试图寻找一个窗口例如,许多人使用一个会话级(或系统 - )宽的“互斥”或互斥锁。我正要为你重写一个,但我发现了一个很好的代码项目文章,展示了这种技术。这并不复杂也很简单。

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

快速预览:

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

希望这有助于。

(编辑:当然你要稍微修改此为您的特定用例,但它演示的总体思路)

+0

这不是Russ所要求的......他不是在制作单个实例应用程序,他只想要一个特定的应用程序窗口只显示一次 – 2009-08-26 16:15:07

+0

urgh,正确。我误解了这一点。那有多难?用一个静态标志跟踪它... sheesh。 – x0n 2009-08-26 16:48:01

+0

@ x0n-这就是为什么我选择我选择的答案,因为使用静态标志跟踪它解决了我的问题。 这很难,因为我从来没有这样做过,而且我的团队中的其他人都被裁掉了一段时间,所以没有太多其他人能够解决问题了。 我也没有在网上看到很多关于winforms和wpf之间互操作的信息,我对这个特定的应用程序非常沉重。 – Russ 2009-08-26 19:03:10

0

我不是一个真正的“适当”的程序员,但我已经实现了这个在WPF应用程序(而不是从一个WinForms之一)通过以下:

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 

主要是因为我创建打开它的子​​外面的窗口对象,只会有一个窗口。任何新的窗口打开子调用将使用相同的对象。但我想这也是托马斯所指的。

就像我说的,不知道这是否会帮助你。

+0

显然我的VB也不是C#。 :) – TravisPUK 2009-08-26 16:26:00

3

这是对我来说很有用的东西。

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

    } 
0

您可以使用XXXwindown.isLoad检查是否加载窗口中创建一个新的窗口前:

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