72

我希望我的窗口仅位于我的应用程序中的所有其他窗口之上。如果我设置一个窗口的 TopMost 属性,它会位于所有应用程序的所有窗口之上,我不希望这样。

4

19 回答 19

52

您需要设置窗口的所有者属性。

您可以通过 showdialog 显示一个窗口以阻止您的主窗口,或者您可以正常显示它并将其置于所有者之上而不阻止所有者。

这是代码隐藏部分的代码示例 - 我省略了所有明显的东西:

namespace StackoverflowExample
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
    }
    void NewWindowAsDialog(object sender, RoutedEventArgs e)
    {
      Window myOwnedDialog = new Window();
      myOwnedDialog.Owner = this;
      myOwnedDialog.ShowDialog();
    }
    void NormalNewWindow(object sender, RoutedEventArgs e)
    {
      Window myOwnedWindow = new Window();
      myOwnedWindow.Owner = this;
      myOwnedWindow.Show();
    }
  }
}
于 2012-06-18T18:40:27.233 回答
17

相反,您可以使用始终为 TopMost 的 Popup,将其装饰为类似于 Window,并将其完全附加到您的 Application 处理主 Window 的 LocationChanged 事件并将 Popup 的 IsOpen 属性设置为 false。

编辑:

我希望你想要这样的东西:

    Window1 window;

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        window = new Window1();
        window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
        window.Topmost = true;
        this.LocationChanged+=OnLocationchanged;
        window.Show();
    }
     
    private void OnLocationchanged(object sender, EventArgs e)
    {
          if(window!=null)
              window.Close();
    }

希望能帮助到你!!!

于 2010-03-30T16:16:50.537 回答
14
CustomWindow cw = new CustomWindow();

cw.Owner = Application.Current.MainWindow;

cw.ShowInTaskbar = false;

cw.ShowDialog() ; 
于 2012-03-27T07:18:27.627 回答
11

在XAML中很容易做到这一点,令人惊讶的是还没有人发布这个答案。在以下示例中,Window定义在 a ResourceLibrary(注意)中,但您也可以在独立式 WPF 资源x:Key上使用此 XAML 绑定。Page

<Window x:Key="other_window" 
        Topmost="{Binding Source={x:Static Application.Current},Path=MainWindow.IsActive,Mode=OneWay}">
    <TextBlock Text="OTHER WINDOW" />
</Window>
于 2016-07-04T21:21:00.957 回答
5

使用激活()方法。这试图将窗口带到前台并激活它。例如窗口 wnd = new xyz(); wnd.Activate();

于 2010-12-06T16:40:23.980 回答
5

在弹出窗口中,使用参数重载方法 Show():

Public Overloads Sub Show(Caller As Window)
    Me.Owner = Caller
    MyBase.Show()
End Sub

然后在主窗口中,调用重载方法 Show():

Dim Popup As PopupWindow

Popup = New PopupWindow
Popup.Show(Me)
于 2011-10-28T19:31:50.583 回答
4

The best way is set this two events to all of windows of your app:

GotKeyboardFocus
LostKeyboardFocus

in this way:

WiondowOfMyApp_GotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
    windowThatShouldBeTopMost.TopMost = true;
}

WiondowOfMyApp_LostKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
    windowThatShouldBeTopMost.TopMost = false;
}
  • and surely all of the windows that you wanted to be top, should be accessible from other windows of your app. in my case I have a base window and another some windows that should be top of my base window, so this was not bad to my base window has instance of each another windows.
于 2011-10-31T06:43:07.700 回答
4

我遇到了和你非常相似的情况。我遇到的大多数搜索都表明我需要做的就是将我希望成为最顶层的窗口的所有者设置为主窗口或任何名为 Show 的窗口。

无论如何,我会继续发布一个对我来说效果很好的解决方案。

我在应该是我的应用程序最顶层的窗口中为 Window.Activated 和 Window.Deactived 创建了事件处理程序。

private void Window_Activated(object sender, EventArgs e)
{
    Topmost = true;
}

private void Window_Deactived(object sender, EventArgs e)
{
    if(Owner == null || Owner.IsActive)
        return;
    bool hasActiveWindow = false;
    foreach(Window ownedWindow in Owner.OwnedWindows)
    {
        if(ownedWindow.IsActive)
            hasActiveWindow = true; 
    }

    if(!hasActiveWindow)
        Topmost = false;
}

这对我很有效。希望这对其他人有用。:o)

于 2011-08-01T16:01:18.207 回答
2

我是OP。经过一番研究和测试,答案是:

不,没有办法做到一点。

于 2010-04-08T16:15:55.737 回答
2

有几个线程,甚至还有一个“topmost”标签。搜索那个,或者直接去这个看起来不错的帖子:

如何仅将一个窗口保留在我的应用程序中的所有其他窗口之上?

于 2010-03-30T15:52:06.360 回答
1

Here's a way to do it: make your "topmost" window subscribe to your other windows GotFocus and LostFocus events and use the following as the event handlers:

class TopMostWindow
{
    void OtherWindow_LostFocus(object sender, EventArgs e)
    {
        this.Topmost = false;
    }

    void OtherWindow_GotFocus(object sender, EventArgs e)
    {
        this.Topmost = true;
    }
}
于 2010-07-04T19:09:01.413 回答
0

尝试这个:

Popup.PlacementTarget = sender as UIElement;
于 2013-10-30T05:43:27.223 回答
0

您可以将其添加到您的 windows 标签

WindowStartupLocation="CenterScreen"

然后,如果您希望您的用户确认它以便继续,您也可以显示它

YourWindow.ShowDialog();

首先在没有 TopMost 参数的情况下尝试一下,看看结果。

于 2010-03-30T20:00:14.723 回答
0

我也遇到了同样的问题,并跟着谷歌回答了这个问题。最近我发现以下内容对我有用。

CustomWindow cw = new CustomWindow();
cw.Owner = this;
cw.ShowDialog();
于 2015-06-27T07:48:50.967 回答
0

这对我有帮助:

Window selector = new Window ();
selector.Show();
selector.Activate();
selector.Topmost = true;
于 2019-11-12T17:29:23.607 回答
0

htis怎么样:

Private Sub ArrangeWindows(Order As Window())
    For I As Integer = 1 To Order.Length -1
        Order(I).Owner = Order(I - 1)
    Next
End Sub
于 2016-10-15T11:38:49.403 回答
0

我刚刚遇到了同样的问题。我有一个具有多个 WPF 窗口的桌面应用程序,并且我需要我的自定义初始屏幕仅位于我的应用程序中的其他窗口之上。当我的启动画面出现时,没有其他窗口打开,但经过一些身份验证后,我确实从启动画面打开了 MainWindow。所以我只是做了一些类似于@GlenSlayden 所做的事情,但在后面的代码中,就像我说的那样,MainWindow 不适合我绑定到:

private void SplashScreen_ContentRendered(object sender, EventArgs e)
{
    // User authentication...
    // ...

    MainWindow mainWindow = new MainWindow();
    SetBinding(SplashScreen.TopmostProperty, new Binding("IsVisible"))
    {
        Source = mainWindow,
        Mode = BindingMode.OneWay,
        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
    };
    mainWindow.Show();
}

现在,当我的程序从 MainWindow 加载所有其他窗口时,启动屏幕在顶部,但是当程序正在验证用户时,它不是最上面的,所以你可以点击其他程序,它会隐藏在它后面。这是我能找到的最接近这个问题的解决方案。它并不完美,因为当我的程序在身份验证后加载时,它仍然超过所有其他应用程序,但就我而言,这并不会持续很长时间。

于 2017-11-20T17:25:34.240 回答
0

我刚刚遇到了同样的问题,发现使用 MVVM 设置所有者时遇到了麻烦,而不会导致应用程序在生产中崩溃。我有一个窗口管理器视图模型,其中包含一个使用窗口 uri 打开窗口的命令 - 我无法在应用程序崩溃的情况下将所有者设置为 App.MainWindow。

所以 -我没有设置所有者,而是将窗口的 TopMost 属性绑定到我的窗口管理器视图模型中的一个属性,该属性指示应用程序当前是否处于活动状态。如果应用程序处于活动状态,则窗口在我想要的顶部。如果它不活动,其他窗口可以覆盖它。

这是我添加到视图模型中的内容:

 public class WindowManagerVM : GalaSoft.MvvmLight.ViewModelBase
    {
        public WindowManagerVM()
        {
            App.Current.Activated += (s, e) => IsAppActive = true;
            App.Current.Deactivated += (s, e) => IsAppActive = false;
        }

        private bool _isAppActive = true;
        public bool IsAppActive
        {
            get => _isAppActive;
            set
            {
                if (_isAppActive != value)
                {
                    _isAppActive = value;
                    RaisePropertyChanged(() => IsAppActive);
                }
            }
        }
    }

这是实现它的 XAML(我在名为 Locator 的应用程序中使用带有 ViewModelLocator 的 MVVM 灯作为静态资源):

<Window Topmost="{Binding WindowManager.IsAppActive, Source={StaticResource Locator}}"/>
于 2019-02-11T16:21:28.707 回答
-1

刚刚学习 C# 并遇到了类似的情况。但找到了一个我认为可能会有所帮助的解决方案。你可能很久以前就想到了这一点。这将从开始一个新项目开始,但您可以在任何项目中使用它。

1) 开始新项目。

2) 转到项目,然后是新建 Windows 窗体,然后选择 Windows 窗体并命名为 Splash。

3) 根据需要设置大小、背景、文本等。

4) 在 Splash.cs 表单的属性下设置 Start Position: CenterScreen 和 TopMost: true

5)form1添加“使用System.Threading;”

6)form1类下添加“Splash splashscreen = new Splash();”

7) form1 添加“splashscreen.Show();” 和“Application.DoEvents();”

8)form1在Events>>Focus>>Activated下添加“Thread.Sleep(4000); splashscreen.Close();”

9) Splash.cs 添加在“Public Splash”下添加“this.BackColor = Color.Aqua;” /可以使用任何颜色

10) 这是 Form1.cs 的代码

public partial class Form1 : Form
{
    Splash splashscreen = new Splash();
    public Form1()
    {
        InitializeComponent();
        splashscreen.Show();
        Application.DoEvents();

    }

    private void Form1_Activated(object sender, EventArgs e)
    {
        Thread.Sleep(4000);
        splashscreen.Close();
    }
}

11) 这是 Splash.cs 上的代码

public partial class Splash : Form
{
    public Splash()
    {
        InitializeComponent();
        this.BackColor = Color.Aqua;
    }
}

12) 我发现如果你不在启动画面中做某事,那么在第一个表单需要激活的时候,屏幕将不会停留在顶部。Thread count 会在 x 秒后消失,所以你的程序是正常的。

于 2018-05-20T22:42:10.180 回答