C# 把主窗口放在前面,不要总是在上面,等待它关闭

C# 把主窗口放在前面,不要总是在上面,等待它关闭,c#,wpf,windows-7,C#,Wpf,Windows 7,我有一个WPF配置实用程序,它只有一个窗口,可以在我的WIX安装程序中运行,也可以在安装后独立运行。SO包含将窗口置于前端的解决方案,但它们使窗口始终位于顶部,或者代码立即返回 当应用程序启动时,我想把窗口放在最前面。它会自动弹出我的MSI对话框。我还想让用户在它上面移动其他窗口(它不应该总是在上面),我想等待窗口在代码中关闭。也许我太挑剔了,因为WPF似乎不支持这一点 目前,我有: MainWindow.Topmost = true; MainWindow.Show(); MainWindow

我有一个WPF配置实用程序,它只有一个窗口,可以在我的WIX安装程序中运行,也可以在安装后独立运行。SO包含将窗口置于前端的解决方案,但它们使窗口始终位于顶部,或者代码立即返回

当应用程序启动时,我想把窗口放在最前面。它会自动弹出我的MSI对话框。我还想让用户在它上面移动其他窗口(它不应该总是在上面),我想等待窗口在代码中关闭。也许我太挑剔了,因为WPF似乎不支持这一点

目前,我有:

MainWindow.Topmost = true;
MainWindow.Show();
MainWindow.Activate();
MainWindow.Topmost = false;
MainWindow.Focus();
除了
MainWindow.Show()
立即返回并继续执行之外,它非常棒。在过去,我们使用

MainWindow.TopMost = true;
MainWindow.ShowDialog();
但是,这个窗口总是位于顶部,并且会妨碍所有其他窗口(不是最佳用户体验)。还有其他选择吗?请随时建议我的架构也不正确。谢谢大家!

而不是使用

MainWindow.ShowDialog();
使用之前的代码后,可以覆盖窗口的关闭事件:

MainWindow.Topmost=true;
MainWindow.Show();
MainWindow.Activate();
MainWindow.Topmost=false;
main window.Focus();
}
/// 
///引发事件。
/// 
///包含事件数据的。
关闭时受保护的覆盖无效(CancelEventArgs e)
{
基数(e);
}
编辑:

在关闭事件中,您可以使用回调(来自调用方)在关闭此窗口后继续

或者,您应该检查安装程序窗口的位置,然后调用

MainWindow.ShowDialog()

这样可以防止主窗口一直处于顶部。 它将阻止调用方执行,直到主窗口关闭

编辑2: 使用topmost可能不是最好的主意,因为它会将对话框移动到任何窗口的前面(即使是用户移动到安装程序前面的窗口)。 也许您应该添加另一个自定义操作,而不使用其他窗口?

MainWindow.ShowDialog();
使用之前的代码后,可以覆盖窗口的关闭事件:

MainWindow.Topmost=true;
MainWindow.Show();
MainWindow.Activate();
MainWindow.Topmost=false;
main window.Focus();
}
/// 
///引发事件。
/// 
///包含事件数据的。
关闭时受保护的覆盖无效(CancelEventArgs e)
{
基数(e);
}
编辑:

在关闭事件中,您可以使用回调(来自调用方)在关闭此窗口后继续

或者,您应该检查安装程序窗口的位置,然后调用

MainWindow.ShowDialog()

这样可以防止主窗口一直处于顶部。 它将阻止调用方执行,直到主窗口关闭

编辑2: 使用topmost可能不是最好的主意,因为它会将对话框移动到任何窗口的前面(即使是用户移动到安装程序前面的窗口)。
也许您应该添加另一个自定义操作而不添加其他窗口?

您可以修改主窗口代码吗?如果是这样,只需将其放在代码后面:

protected override void OnActivated(EventArgs e)
{
    base.OnActivated(e);

    this.Topmost = true;
    this.Topmost = false;
}
然后,无论您使用
.Show()
还是
.ShowDialog()
,每次激活窗口时,它都会向前移动

编辑:如果您不能/不会修改主窗口代码,您可以订阅
激活的
事件:

MainWindow.Activated += new EventHandler(window_Activated);
MainWindow.ShowDialog();  // or .Show()

...

void window_Activated(object sender, EventArgs e)
{
    var window = sender as MainWindow;

    window.Topmost = true;
    window.Topmost = false;
}

你能修改主窗口代码吗?如果是这样,只需将其放在代码后面:

protected override void OnActivated(EventArgs e)
{
    base.OnActivated(e);

    this.Topmost = true;
    this.Topmost = false;
}
然后,无论您使用
.Show()
还是
.ShowDialog()
,每次激活窗口时,它都会向前移动

编辑:如果您不能/不会修改主窗口代码,您可以订阅
激活的
事件:

MainWindow.Activated += new EventHandler(window_Activated);
MainWindow.ShowDialog();  // or .Show()

...

void window_Activated(object sender, EventArgs e)
{
    var window = sender as MainWindow;

    window.Topmost = true;
    window.Topmost = false;
}

当应用程序启动时,我想把它带到最前面。我还想让用户在它上面移动其他窗口(它不应该总是在上面)。。。这是WPF中
窗口的正常行为。我想在代码中等待窗口关闭。。。是什么阻止了这一切的发生?也许你能更清楚地解释一下你的要求吗?@Sheridan我编辑了我的问题,以反映当我的窗口自行打开时,它会在我的MSI对话框下弹出。有问题吗?@Sinatr我想没有。默认情况下,WPF应用程序通过安装程序运行,但也可以在安装后独立运行。我不相信在这两种情况下我都可以设置为它的父窗口。应用程序父窗口是胡说八道,我想在同一个应用程序中设置多个窗口。我错了。你的问题更像是一个问题。当应用程序启动时,我想把它带到前台。我还想让用户在它上面移动其他窗口(它不应该总是在上面)。。。这是WPF中
窗口的正常行为。我想在代码中等待窗口关闭。。。是什么阻止了这一切的发生?也许你能更清楚地解释一下你的要求吗?@Sheridan我编辑了我的问题,以反映当我的窗口自行打开时,它会在我的MSI对话框下弹出。有问题吗?@Sinatr我想没有。默认情况下,WPF应用程序通过安装程序运行,但也可以在安装后独立运行。我不相信在这两种情况下我都可以设置为它的父窗口。应用程序父窗口是胡说八道,我想在同一个应用程序中设置多个窗口。我错了。你的问题更像是一个。嗨,Urutar,我尝试过类似的方法,但似乎需要进行大量测试才能保证它提供与我想要的相同的功能,这似乎是一个黑客。也许你可以添加另一个自定义操作?我不完全熟悉MSI,但这应该是可能的?这是可能的,但我还需要能够独立于我的安装程序运行我的WPF应用程序。如果可以的话,