60

即使其他应用程序在全屏上运行,是否可以使窗口始终保持在顶部?我现在正在使用,TopMost = true但是当其他应用程序在全屏上运行时,我的变得不可见。顺便说一句,它是WindowStyle = None窗户。

编辑:当然不要让其他窗口最小化

4

7 回答 7

58

这不会在 100% 的时间里起作用,但它会在一定程度上改善这种情况。您可以Topmost = trueWindow.Deactivated事件的处理程序中设置:

private void Window_Deactivated(object sender, EventArgs e)
{
    Window window = (Window)sender;
    window.Topmost = true;
}

Deactivated每当您的应用程序失去焦点时(通常是当另一个应用程序请求成为)时,都会调用该事件Topmost,因此这将在此之后将您的应用程序重置为顶部。

于 2013-11-18T15:03:02.807 回答
17

从 MSDN 尝试这个解决方案,它应该适合你。在Window Activated Event添加以下代码:

this.Width   = System.Windows.SystemParameters.PrimaryScreenWidth;
this.Height  = System.Windows.SystemParameters.PrimaryScreenHeight;
this.Topmost = true;
this.Top  = 0;
this.Left = 0;

DeActivated Event添加以下代码

this.Topmost = true;
this.Activate();

来自 MSDN 的原始帖子

于 2014-02-24T09:36:49.817 回答
12

上面的解决方案对我来说都不起作用,所以这就是我最终要做的。它对我来说非常有效。

基本上,要让它保持在顶部,您只需设置失去焦点事件以使其回到顶部。

XAML:

PreviewLostKeyboardFocus="Window_PreviewLostKeyboardFocus"
    

代码背后:

private void Window_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
      var window = (Window)sender;
      window.Topmost = true;
}
于 2018-04-11T14:46:20.920 回答
3

所以我最近遇到了同样的要求。似乎评分最高的答案以及第二个答案对我来说都不起作用。我找到了一个似乎可以完美运行的解决方案,并且在某种程度上遵循了使用 MVVM 的最佳实践。

使用下面的强制窗口到顶部,并且永远不会像其他解决方案一样在更改时失效。

第 1 步:我为我的主客户端窗口创建了一个简单的状态管理器类。在使用直接绑定到我的窗口时,我使用 INotifyPropertyChanged 来保持属性同步。(很重要)

public class ClientStateManager : INotifyPropertyChanged
{
    #region Private Variables
    private bool isForceToTop;
    private bool isClientEnabled;
    #endregion

    #region Public Properties
    public bool IsForceToTop
    {
        get { return isForceToTop; }
        set
        {
            isForceToTop = value;
            NotifyPropertyChanged();
        }
    }
    public bool IsClientEnabled
    {
        get { return isClientEnabled; }
        set
        {
            isClientEnabled = value;
            NotifyPropertyChanged();
        }
    }       
    #endregion

    #region Private Methods
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion

    #region Public Methods
    public void Lock() => this.IsClientEnabled = false;
    public void UnLock() => this.IsClientEnabled = true;
    public void SetTop() => this.IsForceToTop = true;
    public void UnSetTop() => this.IsForceToTop = false;
    #endregion

    #region Public Events
    public event PropertyChangedEventHandler PropertyChanged; 
    #endregion
}

步骤 2.1:将我的状态管理器类添加到我的 ViewModel。(MVVM)

  internal class MainWindowViewModel : INotifyPropertyChanged
  {
    #region Constructor
    public MainWindowViewModel() 
    {
        ClientStateManager = new ClientStateManager();
    }
    #endregion

    #region Public Properties  
    public ClientStateManager ClientStateManager { get; private set; }
    #endregion
  }

步骤 2.2:然后将您的窗口数据上下文设置为您的视图模型。

  private MainWindowViewModel model;
  private MainWindow()
  {
        InitializeComponent();
        this.model = new MainWindowViewModel();
        this.DataContext = model;
  }   

第 3 步:将数据绑定添加到窗口。

  <Window x:Class="Intouch_Work.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:ojects="clr-namespace:Framework.Object;assembly=Framework"
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"     
    mc:Ignorable="d"
    Title="Intouch" Height="800" Width="1100"
    x:Name="mainWindow"
    Topmost="{Binding Path=ClientStateManager.IsForceToTop, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">

所以现在您可以使用在视图模型中初始化的状态管理器对象来管理您的窗口状态。您可以从您的状态管理器调用 SetTop() 来推动它,或者调用 UnSetTop() 来停止它。希望这可以帮助任何想要做同样事情的人。

于 2018-04-10T08:40:20.863 回答
2

如果您希望您的应用程序始终处于领先地位(包括 Windows 8 中的启动界面,以前称为“Metro”),那么您可以在清单文件中指定 UiAccess="True"。这通常由可访问性应用程序(例如屏幕键盘)使用。

从记忆中你需要做三件事;

  1. 请求 UiAccess="True"
  2. 使用公认的证书对应用程序的 exe 文件进行签名。由于我的项目是开源的,因此我从 Certum 获得了免费的代码签名证书。
  3. 将您的应用程序安装到“受信任的位置”,在我的例子中是程序文件目录。我找不到“受信任的位置”的官方定义。
于 2015-03-04T16:08:12.067 回答
0

我有一个主窗口,我想保持在所有内容的顶部(如果用户选中“始终在顶部”。
这对我有用。希望这对某人有所帮助。

// If we want main to stay on top, we set the rest of the menus to Not be top 
if (mnuViewMainWindowAlwaysOnTopo.IsChecked)
{
    this.Topmost = true;
    
    foreach (var window in Application.Current.Windows)
        // Don't change for main window
        if (window.GetType().Name != this.GetType().Name)
            window.Topmost = false;
}
else this.Topmost = false;
于 2014-09-16T16:38:55.640 回答
0

对于工业质量控制应用程序,我需要类似的东西,在该应用程序运行时,非管理员操作员不应该能够最小化或使用专用计算机上的任何其他内容,甚至不能Windows+D调出桌面。我发现实现这一目标的最干净、最简单的方法是:

  1. 设置正确的WidthHeightWindowStyle和属性。WindowStateTopmost
  2. 处理一些相关事件:StateChanged, Deactivated, LostFocuse, LostMouseCapture,LostKeyboardFocusPreviewLostKeyboardFocus.
  3. ALT+F4使用或自定义按钮处理关闭事件)。

不需要 P/Invoke,这是完整的代码:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += OnLoaded;
            Closing += OnClosing;
            StateChanged += OnStateChanged;
            Deactivated += (sender, args) => Activate();
            LostFocus += (sender, args) => Focus();
            LostMouseCapture += (sender, args) => Mouse.Capture(this);
            LostKeyboardFocus += (sender, args) => Keyboard.Focus(this);
            PreviewLostKeyboardFocus += (sender, args) => Keyboard.Focus(this);
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            Width = SystemParameters.PrimaryScreenWidth;
            Height = SystemParameters.PrimaryScreenHeight;
            WindowStyle = WindowStyle.None;
            WindowState = WindowState.Maximized;
            Topmost = true;
            // Other stuff here
        }

        private void OnClosing(object sender, CancelEventArgs e)
        {
            // You might want to allow only some users to close the app
            if (MessageBox.Show("Are you an admin?", "Admin Check", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.No)
               e.Cancel = true;
        }

        private void OnStateChanged(object sender, EventArgs e)
        {
            if (WindowState == WindowState.Minimized)
                WindowState = WindowState.Maximized;
        }
    }

您还可以将其中的一些放在 XAML 中:

<Window x:Class="FullScreen.MainWindow"
        ...
        Title="MainWindow"
        WindowState="Maximized"
        WindowStyle="None" 
        Topmost="True">
    <Grid>
        
    </Grid>
</Window>

于 2021-02-15T09:40:58.663 回答