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

时间:2010-03-30 15:43:58

标签: c# wpf topmost

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

19 个答案:

答案 0 :(得分:37)

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

您可以通过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();
    }
  }
}

答案 1 :(得分:15)

相反,你可以使用一个总是TopMost的Popup,像Window一样装饰它并将它完全附加到你的Application处理主窗口的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();
    }

希望它有所帮助!!!

答案 2 :(得分:11)

CustomWindow cw = new CustomWindow();

cw.Owner = Application.Current.MainWindow;

cw.ShowInTaskbar = false;

cw.ShowDialog() ; 

答案 3 :(得分:5)

使用Activate()方法。这会尝试将窗口置于前台并激活它。 例如Window wnd = new xyz(); wnd.Activate();

答案 4 :(得分:5)

最好的方法是将这两个事件设置为应用的所有窗口:

GotKeyboardFocus
LostKeyboardFocus

以这种方式:

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

WiondowOfMyApp_LostKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
    windowThatShouldBeTopMost.TopMost = false;
}
  • 当然,您想要成为顶级的所有窗口都应该可以从您应用的其他窗口访问。 在我的情况下,我有一个基本窗口和另一些应该在我的基本窗口顶部的窗口,所以这对我的基本窗口有不同的每个窗口的实例。

答案 5 :(得分:5)

XAML 中很容易做到,并且没有人发布这个答案感到惊讶。在以下示例中,WindowResourceLibrary中定义(请注意x:Key),但您也可以在独立的Page样式的WPF资源上使用此XAML绑定。

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

答案 6 :(得分:4)

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

无论如何,我会继续发布一个对我有用的解决方案。

我在窗口中创建了Window.Activated和Window.Deactived的事件处理程序,该窗口应该是关于我的应用程序的Topmost。

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)

答案 7 :(得分:4)

在弹出窗口中,使用参数:

重载方法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)

答案 8 :(得分:2)

有几个主题,甚至还有一个“最顶层”的标签。搜索,或直接转到这篇看起来不错的帖子:

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

答案 9 :(得分:1)

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

不,没有办法完全那个。

答案 10 :(得分:1)

这是一种方法:让你的“最顶层”窗口订阅你的其他windows GotFocus和LostFocus事件,并使用以下作为事件处理程序:

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

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

答案 11 :(得分:0)

您可以将其添加到Windows代码

WindowStartupLocation="CenterScreen"

如果您希望用户对其进行确认以继续

,您也可以显示它
YourWindow.ShowDialog();

首先尝试不使用TopMost参数并查看结果。

答案 12 :(得分:0)

试试这个:

Popup.PlacementTarget = sender as UIElement;

答案 13 :(得分:0)

我也面临同样的问题,并跟着谷歌这个问题。最近我发现以下内容对我有用。

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

答案 14 :(得分: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

答案 15 :(得分: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加载所有其他窗口时,启动画面位于顶部,但是当程序验证用户时,它不是最顶层的,所以你可以点击其他一些程序它会隐藏在它背后。这是我能找到解决这个问题的最接近的方法。它并不完美,因为在我的程序在验证后加载时,它仍然超过所有其他应用程序的顶部,但在我的情况下这不会很长。

答案 16 :(得分:0)

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

1)开始新项目。

2)转到Project,然后转到New Windows窗体,然后选择Windows Form并命名Splash。

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

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

5)form1 add&#34; using System.Threading;&#34;

6)class1在class add&#34; Splash splashscreen = new Splash();&#34;

7)form1 add&#34; splashscreen.Show();&#34;和#34; Application.DoEvents();&#34;

8)form1在事件&gt;&gt;焦点&gt;&gt;激活添加&#34; Thread.Sleep(4000); splashscreen.Close();&#34;

9)Splash.cs添加&#34; Public Splash&#34;添加&#34; this.BackColor = Color.Aqua;&#34; /可以使用任何颜色

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)我发现如果你没有在飞溅中做某事,那么在第一张表格需要激活的时候,屏幕不会保持在顶部。  后,线程计数将在启动后消失,因此您的程序正常。

答案 17 :(得分:0)

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

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

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

 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的应用中将MVVM light与ViewModelLocator一起用作静态资源):

<Window Topmost="{Binding WindowManager.IsAppActive, Source={StaticResource Locator}}"/>

答案 18 :(得分:0)

这对我有帮助:

Window selector = new Window ();
selector.Show();
selector.Activate();
selector.Topmost = true;