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

我希望我的窗口在所有其他窗口 只在我的申请表上之上。如果我设置一个窗口的 TopMost 属性,它就会位于所有应用程序窗口的顶部,我不希望这样。

118704 次浏览

有几个线程,甚至有一个“最高”标签。你可以在这里搜索,或者直接点击这篇看起来不错的文章:

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

相反,你可以使用一个始终是 TopMost 的弹出窗口,将它装饰成类似于一个窗口的样子,然后用应用程序处理主窗口的 LocationChanged 事件并将弹出窗口的 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();
}

希望能有帮助! ! !

您可以将其添加到 Windows 标记中

WindowStartupLocation="CenterScreen"

然后,如果您希望您的用户为了继续操作而确认它,那么您也可以显示它

YourWindow.ShowDialog();

首先尝试不使用 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;
}
}

使用 Activate ()方法。该方法尝试将窗口显示在前台并激活它。 例如 Window wnd = new xyz () ; 启动() ;

我遇到了和你非常相似的情况。我遇到的大多数 搜索声明,所有我需要做的是设置所有者的窗口,我希望是最高的主窗口或任何窗口,称为显示。

无论如何,我将继续并发布一个解决方案,为我工作得很好。

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

它对我很有用,希望对其他人也有用

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

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

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

Dim Popup As PopupWindow


Popup = New PopupWindow
Popup.Show(Me)

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

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;
}
  • 当然,所有的窗口,你想要在顶部,应该可以从你的应用程序的其他窗口访问。 在我的例子中,我有一个基本窗口和另外一些应该在基本窗口顶部的窗口,所以这对于我的基本窗口来说是不错的,它们有彼此窗口的实例。
CustomWindow cw = new CustomWindow();


cw.Owner = Application.Current.MainWindow;


cw.ShowInTaskbar = false;


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

试试这个:

Popup.PlacementTarget = sender as UIElement;

我也面临着同样的问题,并跟随谷歌来解决这个问题。最近我发现下面的方法对我很有效。

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

XAML中做起来很简单,而且令人惊讶的是还没有人发布这个答案。在下面的示例中,Window是在 ResourceLibrary中定义的(请注意 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>

这个怎么样:

Private Sub ArrangeWindows(Order As Window())
For I As Integer = 1 To Order.Length -1
Order(I).Owner = Order(I - 1)
Next
End Sub

我也遇到了同样的问题。我有一个桌面应用程序,有多个 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 加载所有其他窗口时,启动画面在顶部,但当程序正在验证用户身份时,它不在顶部,所以你可以点击其他程序,它将隐藏在它后面。这是我能找到的最接近解决这个问题的方法了。它并不完美,因为当我的程序在身份验证后加载时,它仍然优于所有其他应用程序,但在我的情况下,这不会持续很长时间。

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

1)开展新项目。

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

3)根据需要设置尺寸、背景、文字等。

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

5) form1加上“ using System. Threading;”

6)在类别中加入“ Splash splashscreen = new Splash () ;

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

8) form1在 Events > > Focus > > Activated add“ 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)我发现,如果你不做点什么,那么屏幕将不会停留在顶部的时候,第一个形式需要激活。 线程计数将在 x 秒后消失,因此程序是正常的。

我只是遇到了同样的问题,并发现使用 MVVM 设置所有者而不导致应用程序崩溃的问题。我有一个窗口管理器视图模型,其中包括一个命令,以打开一个窗口使用该窗口的 uri-我不能设置的所有者应用程序。不会崩溃的主窗口。

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

下面是我在视图模型中添加的内容:

 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 (我使用 MVVM light 和 ViewModelLocator 作为我的应用程序 Locator 中的静态资源) :

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

这就是帮助我的东西:

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

这是我对这个问题的第二个回答; 我发现了另一种非常有效的技术,用于管理属于单个 Application的多个 Window实例

正如许多人所指出的,Window.Owner属性是关键。当你的应用程序处于活动状态时——意味着它的一个窗口 IsActive——你希望所有窗口的 Owner属性都是 null。这允许在应用程序的不同窗口之间进行相同的切换。

但是,当您的应用程序是 没有活动,您希望您的 < strong > non-MainWindow每个窗口的 Window.Owner属性设置为您的 MainWindow。这样,你可以使用你的应用程序的任何窗口重新激活,你的应用程序的所有窗口将恢复 在所有其他应用程序面前

每次重新激活应用程序时,将 Window.Owner值切换回 nullApplication.OnActivatedApplication.OnDeactivated方法对此是完美的。

您必须单独保留所有窗口的列表,因为使用这种变通方法意味着您不能方便地在 MainWindow上使用 Window.OwnedWindows属性,以便在执行这些调整时使用。

public partial class MyApp : Application
{
// not shown: keep this list of all your non-main windows updated...
public List<Window> rgw = new List<Window>();


protected override void OnActivated(EventArgs e)
{
// when app is ACTIVE, set all `Owner` values to null...
rgw.ForEach(w => w.Owner = null);


base.OnActivated(e);
}


protected override void OnDeactivated(EventArgs e)
{
// set `Owner` on all non-main Windows only when not-active
rgw.ForEach(w => w.Owner = Current.MainWindow);


base.OnDeactivated(e);
}


// etc..
}