我有一个WPF窗口,我从winform应用程序内部启动。我只想允许一次打开该WPF窗口的一次实例,并且如果用户试图再次打开它,则不会警告该用户。
我遇到了一个问题,但是尝试搜索正在打开的WPF窗口,因为窗口是从winform启动的。我正常做的是在搜索winform时,我搜索Application.Current.OpenForms
中存在的winform的任何实例,并在WPF中搜索Application.Current.Windows
我遇到的问题是,当从winform内部启动时,System.Windows.Application.Current
为null,因此我无法以这种方式搜索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;
}
}
}
答案 0 :(得分:6)
您可以使用单个静态变量,而不是搜索静态应用程序对象,而只是在窗口中跟踪它。只需在窗口中保留一个变量:
private static frmCaseWpf openWindow = null; // Assuming your class name is frmCaseWpf
在初始化例程或OnLoaded中创建窗口时,具体取决于您希望它如何工作..:
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;关闭窗口时也是如此。
答案 1 :(得分: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();
}
}
答案 2 :(得分:0)
最好将frmCaseWpf类设为singleton。这样你就不能创建另一个实例
答案 3 :(得分:0)
许多人使用会话(或系统)宽的“Mutex”或互斥锁,而不是尝试搜索Window实例。我打算为你重写一个,但我找到了一篇很好的代码项目文章,展示了这项技术。它并不复杂而且非常简单。
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);
}
希望这有帮助。
(编辑:当然,你必须根据你的特定用例略微修改它,但它会演示一般的想法)
答案 4 :(得分: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
基本上因为我在打开它的sub之外创建窗口对象,所以只有一个窗口。对窗口open sub的任何新调用都将使用相同的对象。但我想这也是托马斯所指的。
就像我说的那样,不确定这对你有没有帮助。
答案 5 :(得分:0)
您可以在创建新窗口之前使用XXXwindown.isLoad检查窗口是否已加载:
if ( !ChildWindow.IsLoaded)
{
childWindow= new ChildWindow();
childWindow.Show();
}