c# wpf topmost

c# - WPF siempre en la cima



topmost (6)

Así que me encontré con el mismo requisito recientemente. Parece que la respuesta mejor calificada y la segunda no funcionaron para mí. Encontré una solución que parece funcionar sin problemas y de alguna forma cumple con las mejores prácticas al usar MVVM.

Usar el siguiente fuerza la ventana hacia la parte superior y nunca caduca al cambiar como las otras soluciones.

Paso 1: Creé una clase de administrador de estado simple para la ventana principal de mi cliente. Utilicé INotifyPropertyChanged para mantener las propiedades sincronizadas cuando utilizo un enlace directo a mi ventana. (muy importante)

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 }

Paso 2.1: Agregué mi clase de administrador de estado a mi ViewModel. (MVVM)

internal class MainWindowViewModel : INotifyPropertyChanged { #region Constructor public MainWindowViewModel() { ClientStateManager = new ClientStateManager(); } #endregion #region Public Properties public ClientStateManager ClientStateManager { get; private set; } #endregion }

Paso 2.2: Luego establece el contexto de datos de tu ventana en tu modelo de vista.

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

Paso 3: agregue su enlace de datos a su ventana.

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

Entonces ahora puede administrar su estado de ventana usando el objeto del administrador de estado inicializado dentro del Modelo de Vista. Puede llamar a SetTop () desde su administrador de estado para que lo adelante, o hasta UnSetTop () para detenerlo. Espero que esto ayude a cualquiera que busque hacer lo mismo.

¿Es posible hacer que una ventana permanezca siempre en la parte superior incluso cuando se está ejecutando otra aplicación en pantalla completa? Ahora estoy usando TopMost = true pero cuando otra aplicación se ejecuta en pantalla completa, la mina se vuelve invisible. Es ventana WindowStyle = None por cierto.

Editar : Y no dejes que otra ventana minimalize por supuesto


Esto no funcionará el 100% del tiempo, pero mejorará la situación un poco. Puede establecer Topmost = true en el controlador para el evento Window.Deactivated :

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

Se llamará al evento Deactivated cada vez que su aplicación pierda el foco (a menudo cuando otra aplicación solicite ser Topmost ) y así reiniciará su aplicación en la parte superior después de esto.


Ninguna de las soluciones anteriores funcionó, así que esto es lo que terminé haciendo. Funcionó perfectamente para mí.

Básicamente, para mantenerlo en la parte superior simplemente configura el evento de pérdida de foco para que vuelva al principio.

XAML:

PreviewLostKeyboardFocus="Window_PreviewLostKeyboardFocus"

Código detrás:

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


Pruebe esta solución de MSDN, debería funcionar para usted. En el Window Activated Event la Window Activated Event agregue el siguiente código:

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

en el DeActivated Event agrega el siguiente código

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

Publicación original de MSDN


Si desea que su aplicación se mantenga al tanto de TODO (incluida la interfaz de inicio en Windows 8, anteriormente conocida como "Metro"), puede especificar UiAccess = "True" en su archivo de manifiesto. Esto es típicamente usado por aplicaciones de accesibilidad como teclados en pantalla.

De memoria necesitas hacer 3 cosas;

  1. Solicitud UiAccess = "True"
  2. Firme el archivo exe de su aplicación con un certificado reconocido. Obtuve un certificado de firma de código gratuito de Certum, ya que mi proyecto es de código abierto.
  3. Instale su aplicación en una "ubicación de confianza", que en mi caso era el directorio de archivos del programa. No hay una definición oficial de "Ubicación de confianza" que pueda encontrar.

Tenía una ventana principal que quería mantener al tanto (si el usuario marcaba "siempre arriba").
Esto funcionó para mí. Espero que esto ayude a alguien.

// 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 (Window 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; }