如何使WPF窗口位于我的应用程序的所有其他窗口之上(不是系统范围)?

时间:2022-06-19 16:57:19

I want my window to be on top of all other windows in my application only. If I set the TopMost property of a window, it becomes on top of all windows of all applications and I don't want that.

我希望我的窗口只位于应用程序中所有其他窗口的顶部。如果我设置窗口的最顶层属性,它就会出现在所有应用程序的窗口之上,我不想这样。

17 个解决方案

#1


29  

You need to set the owner property of the window.

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

You can show a window via showdialog in order to block your main window, or you can show it normal and have it ontop of the owner without blocking the owner.

您可以通过showdialog显示一个窗口以阻止主窗口,也可以正常显示,并将其放在所有者的顶部,而不阻塞所有者。

here is a codeexample of the codebehind part - I left out all obvious stuff:

下面是代码背后的代码示例——我省略了所有明显的东西:

namespace *Example
{
  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();
    }
  }
}

#2


16  

Instead you can use a Popup that will be TopMost always, decorate it similar to a Window and to attach it completely with your Application handle the LocationChanged event of your main Window and set IsOpen property of Popup to false.

相反,您可以使用一个弹出窗口,它将始终是最高的,将它与窗口相似,并将它与应用程序完全连接,处理主窗口的LocationChanged事件,并将弹出窗口的IsOpen属性设置为false。

Edit:

I hope you want something like this:

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

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

Hope it helps!!!

希望它帮助! ! !

#3


8  

CustomWindow cw = new CustomWindow();

cw.Owner = Application.Current.MainWindow;

cw.ShowInTaskbar = false;

cw.ShowDialog() ; 

#4


5  

use the Activate() method. This attempts to bring the window to the foreground and activate it. e.g. Window wnd = new xyz(); wnd.Activate();

使用激活()方法。这将尝试将窗口带到前台并激活它。窗口wnd =新的xyz();wnd.Activate();

#5


5  

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.
  • 当然所有的窗户,你想要,应该可以从其他窗口的应用,在我的例子中,我有一个基本窗口和另一些windows窗口应该我的基地,这是不坏,我基本窗口实例的另一个窗口。

#6


4  

I ran into a very similar situation as you. Most of the searches I came across stated all I needed to do was set the Owner of the windows I wish to be Topmost to the main window or whatever window that called Show.

我和你的处境很相似。我遇到的大多数搜索都表明,我所需要做的就是设置我希望位于主窗口或任何称为Show的窗口的最上面的窗口的所有者。

Anyways, I'll go ahead and post a solution that worked well for me.

无论如何,我将继续发布一个适合我的解决方案。

I created event handlers for Window.Activated and Window.Deactived in the window that was supposed to be Topmost with respect to my application.

我为Window创建了事件处理程序。激活和窗口。在我的应用中应该是最上面的窗口中。

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

It works great for me. Hopefully this is useful to someone else out there. :o)

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

#7


4  

In the popup window, overloads the method Show() with a parameter:

在弹出窗口中,重载带有参数的Show()方法:

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

Then in the Main window, call your overloaded method Show():

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

Dim Popup As PopupWindow

Popup = New PopupWindow
Popup.Show(Me)

#8


2  

There are several threads, there's even a "topmost" tag. Search on that, or go directly to this post which looks good:

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

How to keep a window on top of all other windows in my application only?

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

#9


2  

Simple to do it in XAML, and surprised that nobody posted this answer yet. In the following example, the Window is defined in a ResourceLibrary (notice the x:Key), but you can also use this XAML binding on a standalone Page-style WPF resource.

在XAML中做这个很简单,但是奇怪的是还没有人发布这个答案。在下面的示例中,窗口是在ResourceLibrary中定义的(注意x:Key),但是您也可以在独立页面样式的WPF资源上使用XAML绑定。

<Window x:Key="other_window" 
        Topmost="{Binding Source={x:Static Application.Current},Path=MainWindow.IsActive,Mode=OneWay}">
    <TextBlock Text="OTHER WINDOW" />
</Window>

#10


1  

I'm the OP. After some research and testing, the answer is:

经过一些研究和测试,我的答案是:

No, there is no way to do exactly that.

不,没有办法做到这一点。

#11


0  

You can add this to your windows tags

您可以将其添加到您的windows标记中。

WindowStartupLocation="CenterScreen"

Then you can also display it if you want your users to acknowledge it in order to proceed

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

YourWindow.ShowDialog();

First try it without TopMost parameters and see the results.

首先尝试不带最上面的参数,并查看结果。

#12


0  

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:

这里有一个方法:让你的“topmost”窗口订阅你的其他窗口GotFocus和LostFocus事件,并使用下面的事件处理程序:

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

    void OtherWindow_GotFocus(object sender, EventArgs e)
    {
        this.Topmost = true;
    }
}

#13


0  

Try this:

试试这个:

Popup.PlacementTarget = sender as UIElement;

#14


0  

How about htis:

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

#15


0  

I too faced the same problem and followed Google to this question. Recently I found the following worked for me.

我也遇到了同样的问题,于是跟随谷歌回答了这个问题。最近我发现以下方法对我很有效。

CustomWindow cw = new CustomWindow();
cw.Owner = this;
cw.ShowDialog();

#16


0  

I just ran into this same issue. I have a desktop app that has multiple WPF windows, and I needed my custom splash screen to be on top of the other windows in my app only. No other windows are open when my splash screen comes up, but I do open the MainWindow from my splash screen after some authentication. So I just did something similar to what @GlenSlayden did but in code behind since, like I said, the MainWindow isn't up for me to bind to:

我遇到了同样的问题。我有一个桌面应用程序,它有多个WPF的窗口,我需要我的自定义启动屏幕在我的应用程序的其他窗口之上。当我的启动屏幕出现时,没有其他窗口是打开的,但是经过一些验证之后,我确实从启动屏幕上打开了主窗口。所以我做了一些类似于@GlenSlayden做的事情但是在代码后面,就像我说的,主窗口不能绑定到:

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

Now while my program is loading all the other windows from the MainWindow, the splash screen is on top, but while the program is authenticating the user, it's not topmost, so you can click away on some other program and it will hide behind it. It's the closest thing I could find to a solution for this problem. It's not perfect because it still goes over top of all other applications while my program is loading after authentication, but that's not for very long in my case.

现在,当我的程序从主窗口加载所有其他窗口时,启动屏幕在顶部,但是当程序正在验证用户时,它不是最高的,所以你可以单击其他程序,它会隐藏在后面。这是我能找到的最接近解决这个问题的方法。它并不完美,因为在我的程序在认证后加载时,它仍然超过了所有其他应用程序,但在我的例子中,这种情况不会持续很久。

#17


0  

Just learning C# and ran across similar situation. but found a solution that I think may help. You may have figured this a long time ago. this will be from starting a new project but you can use it in any.

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

1) Start new project.

1)开始新项目。

2) go to Project, then New Windows form, then select Windows Form and name Splash.

2)进入Project,新建Windows窗体,选择Windows窗体并命名Splash。

3) set size, background, text, etc as desired.

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

4) Under Properties of the Splash.cs form set Start Position: CenterScreen and TopMost: true

4)飞溅属性下。cs表单设置起始位置:CenterScreen和TopMost: true。

5) form1 add "using System.Threading;"

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

6) form1 under class add "Splash splashscreen = new Splash();"

6)在类下增加“Splash splashscreen = new Splash()”;

7) form1 add "splashscreen.Show();" and "Application.DoEvents();"

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

8) form1 Under Events>>Focus>>Activated add "Thread.Sleep(4000); splashscreen.Close();"

8) form1在事件>>焦点>>激活添加“Thread.Sleep(4000)”;splashscreen.Close();“

9) Splash.cs add under "Public Splash" add "this.BackColor = Color.Aqua;" /can use any color

9)飞溅。cs添加“公共水花”加“这个”。背景色= Color.Aqua;”/可以使用任何颜色

10) This is the code for Form1.cs

这是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) this is the code on Splash.cs

这是关于Splash.cs的代码

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

12) I found that if you do NOT do something in the splash then the screen will not stay on the top for the time the first form needs to activate. The Thread count will disappear the splash after x seconds, so your program is normal.

12)我发现如果你不做点什么,屏幕就不会在第一个表单需要激活的时候停留在顶部。线程计数将在x秒后消失,因此您的程序是正常的。

#1


29  

You need to set the owner property of the window.

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

You can show a window via showdialog in order to block your main window, or you can show it normal and have it ontop of the owner without blocking the owner.

您可以通过showdialog显示一个窗口以阻止主窗口,也可以正常显示,并将其放在所有者的顶部,而不阻塞所有者。

here is a codeexample of the codebehind part - I left out all obvious stuff:

下面是代码背后的代码示例——我省略了所有明显的东西:

namespace *Example
{
  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();
    }
  }
}

#2


16  

Instead you can use a Popup that will be TopMost always, decorate it similar to a Window and to attach it completely with your Application handle the LocationChanged event of your main Window and set IsOpen property of Popup to false.

相反,您可以使用一个弹出窗口,它将始终是最高的,将它与窗口相似,并将它与应用程序完全连接,处理主窗口的LocationChanged事件,并将弹出窗口的IsOpen属性设置为false。

Edit:

I hope you want something like this:

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

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

Hope it helps!!!

希望它帮助! ! !

#3


8  

CustomWindow cw = new CustomWindow();

cw.Owner = Application.Current.MainWindow;

cw.ShowInTaskbar = false;

cw.ShowDialog() ; 

#4


5  

use the Activate() method. This attempts to bring the window to the foreground and activate it. e.g. Window wnd = new xyz(); wnd.Activate();

使用激活()方法。这将尝试将窗口带到前台并激活它。窗口wnd =新的xyz();wnd.Activate();

#5


5  

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.
  • 当然所有的窗户,你想要,应该可以从其他窗口的应用,在我的例子中,我有一个基本窗口和另一些windows窗口应该我的基地,这是不坏,我基本窗口实例的另一个窗口。

#6


4  

I ran into a very similar situation as you. Most of the searches I came across stated all I needed to do was set the Owner of the windows I wish to be Topmost to the main window or whatever window that called Show.

我和你的处境很相似。我遇到的大多数搜索都表明,我所需要做的就是设置我希望位于主窗口或任何称为Show的窗口的最上面的窗口的所有者。

Anyways, I'll go ahead and post a solution that worked well for me.

无论如何,我将继续发布一个适合我的解决方案。

I created event handlers for Window.Activated and Window.Deactived in the window that was supposed to be Topmost with respect to my application.

我为Window创建了事件处理程序。激活和窗口。在我的应用中应该是最上面的窗口中。

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

It works great for me. Hopefully this is useful to someone else out there. :o)

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

#7


4  

In the popup window, overloads the method Show() with a parameter:

在弹出窗口中,重载带有参数的Show()方法:

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

Then in the Main window, call your overloaded method Show():

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

Dim Popup As PopupWindow

Popup = New PopupWindow
Popup.Show(Me)

#8


2  

There are several threads, there's even a "topmost" tag. Search on that, or go directly to this post which looks good:

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

How to keep a window on top of all other windows in my application only?

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

#9


2  

Simple to do it in XAML, and surprised that nobody posted this answer yet. In the following example, the Window is defined in a ResourceLibrary (notice the x:Key), but you can also use this XAML binding on a standalone Page-style WPF resource.

在XAML中做这个很简单,但是奇怪的是还没有人发布这个答案。在下面的示例中,窗口是在ResourceLibrary中定义的(注意x:Key),但是您也可以在独立页面样式的WPF资源上使用XAML绑定。

<Window x:Key="other_window" 
        Topmost="{Binding Source={x:Static Application.Current},Path=MainWindow.IsActive,Mode=OneWay}">
    <TextBlock Text="OTHER WINDOW" />
</Window>

#10


1  

I'm the OP. After some research and testing, the answer is:

经过一些研究和测试,我的答案是:

No, there is no way to do exactly that.

不,没有办法做到这一点。

#11


0  

You can add this to your windows tags

您可以将其添加到您的windows标记中。

WindowStartupLocation="CenterScreen"

Then you can also display it if you want your users to acknowledge it in order to proceed

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

YourWindow.ShowDialog();

First try it without TopMost parameters and see the results.

首先尝试不带最上面的参数,并查看结果。

#12


0  

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:

这里有一个方法:让你的“topmost”窗口订阅你的其他窗口GotFocus和LostFocus事件,并使用下面的事件处理程序:

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

    void OtherWindow_GotFocus(object sender, EventArgs e)
    {
        this.Topmost = true;
    }
}

#13


0  

Try this:

试试这个:

Popup.PlacementTarget = sender as UIElement;

#14


0  

How about htis:

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

#15


0  

I too faced the same problem and followed Google to this question. Recently I found the following worked for me.

我也遇到了同样的问题,于是跟随谷歌回答了这个问题。最近我发现以下方法对我很有效。

CustomWindow cw = new CustomWindow();
cw.Owner = this;
cw.ShowDialog();

#16


0  

I just ran into this same issue. I have a desktop app that has multiple WPF windows, and I needed my custom splash screen to be on top of the other windows in my app only. No other windows are open when my splash screen comes up, but I do open the MainWindow from my splash screen after some authentication. So I just did something similar to what @GlenSlayden did but in code behind since, like I said, the MainWindow isn't up for me to bind to:

我遇到了同样的问题。我有一个桌面应用程序,它有多个WPF的窗口,我需要我的自定义启动屏幕在我的应用程序的其他窗口之上。当我的启动屏幕出现时,没有其他窗口是打开的,但是经过一些验证之后,我确实从启动屏幕上打开了主窗口。所以我做了一些类似于@GlenSlayden做的事情但是在代码后面,就像我说的,主窗口不能绑定到:

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

Now while my program is loading all the other windows from the MainWindow, the splash screen is on top, but while the program is authenticating the user, it's not topmost, so you can click away on some other program and it will hide behind it. It's the closest thing I could find to a solution for this problem. It's not perfect because it still goes over top of all other applications while my program is loading after authentication, but that's not for very long in my case.

现在,当我的程序从主窗口加载所有其他窗口时,启动屏幕在顶部,但是当程序正在验证用户时,它不是最高的,所以你可以单击其他程序,它会隐藏在后面。这是我能找到的最接近解决这个问题的方法。它并不完美,因为在我的程序在认证后加载时,它仍然超过了所有其他应用程序,但在我的例子中,这种情况不会持续很久。

#17


0  

Just learning C# and ran across similar situation. but found a solution that I think may help. You may have figured this a long time ago. this will be from starting a new project but you can use it in any.

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

1) Start new project.

1)开始新项目。

2) go to Project, then New Windows form, then select Windows Form and name Splash.

2)进入Project,新建Windows窗体,选择Windows窗体并命名Splash。

3) set size, background, text, etc as desired.

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

4) Under Properties of the Splash.cs form set Start Position: CenterScreen and TopMost: true

4)飞溅属性下。cs表单设置起始位置:CenterScreen和TopMost: true。

5) form1 add "using System.Threading;"

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

6) form1 under class add "Splash splashscreen = new Splash();"

6)在类下增加“Splash splashscreen = new Splash()”;

7) form1 add "splashscreen.Show();" and "Application.DoEvents();"

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

8) form1 Under Events>>Focus>>Activated add "Thread.Sleep(4000); splashscreen.Close();"

8) form1在事件>>焦点>>激活添加“Thread.Sleep(4000)”;splashscreen.Close();“

9) Splash.cs add under "Public Splash" add "this.BackColor = Color.Aqua;" /can use any color

9)飞溅。cs添加“公共水花”加“这个”。背景色= Color.Aqua;”/可以使用任何颜色

10) This is the code for Form1.cs

这是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) this is the code on Splash.cs

这是关于Splash.cs的代码

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

12) I found that if you do NOT do something in the splash then the screen will not stay on the top for the time the first form needs to activate. The Thread count will disappear the splash after x seconds, so your program is normal.

12)我发现如果你不做点什么,屏幕就不会在第一个表单需要激活的时候停留在顶部。线程计数将在x秒后消失,因此您的程序是正常的。