¿Cómo puedo llevar mi aplicación WPF al frente del escritorio? Hasta ahora he intentado:
SwitchToThisWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle, true);
SetWindowPos(new WindowInteropHelper(Application.Current.MainWindow).Handle, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
SetForegroundWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle);
Ninguno de los cuales está haciendo el trabajo ( Marshal.GetLastWin32Error()
dice que estas operaciones se completaron con éxito, y los atributos P / Invoke para cada definición sí lo tienen SetLastError=true
).
Si creo una nueva aplicación WPF en blanco y llamo SwitchToThisWindow
con un temporizador, funciona exactamente como se esperaba, por lo que no estoy seguro de por qué no funciona en mi caso original.
Editar : estoy haciendo esto junto con una tecla de acceso rápido global.
Respuestas:
Intenta poner la ventana en primer plano y la activa.
Eso debería ser el truco, a menos que lo haya entendido mal y desee un comportamiento siempre en la cima. En ese caso quieres:
fuente
Topmost
propiedad es una mala práctica ya que puede oscurecer otros cuadros de diálogo emergentes y tener un comportamiento inesperado.if (myWindow.WindowState == WindowState.Minimized) myWindow.WindowState = WindowState.Normal;
Curiosamente, también conservará las ventanas maximizadas y no las revertirá a un estado Normal.He encontrado una solución que lleva la ventana a la parte superior, pero se comporta como una ventana normal:
fuente
Window.Focus()
. Esto quitará el foco de lo que el usuario está escribiendo actualmente en un cuadro de texto, lo que es increíblemente frustrante para los usuarios finales. El código anterior funciona bien sin él.En caso de que necesite que la ventana esté al frente la primera vez que se carga, debe usar lo siguiente:
fuente
Para que sea una copia y pegue rápida:
use esta
DoOnProcess
ventana principal de ' método para mover el proceso' a primer plano (pero no para robar el foco de otras ventanas)HTH
fuente
process.MainWindowHandle
?hWnd
. FWIW unHwndSource
objeto funcionó bien.Sé que esta pregunta es bastante antigua, pero acabo de encontrarme con este escenario preciso y quería compartir la solución que he implementado.
Como se menciona en los comentarios de esta página, varias de las soluciones propuestas no funcionan en XP, lo que necesito admitir en mi escenario. Si bien estoy de acuerdo con el sentimiento de @Matthew Xavier de que, en general, esta es una mala práctica de UX, hay momentos en los que es una experiencia de usuario totalmente plausible.
La solución para llevar una ventana WPF a la cima me la proporcionó el mismo código que estoy usando para proporcionar la tecla de acceso rápido global. Un artículo de blog de Joseph Cooney contiene un enlace a sus ejemplos de código que contiene el código original.
Limpié y modifiqué un poco el código, y lo implementé como un método de extensión para System.Windows.Window. He probado esto en XP 32 bit y Win7 64 bit, los cuales funcionan correctamente.
Espero que este código ayude a otros que enfrentan este problema.
fuente
this.Activate()
parece funcionar algunas veces.Si el usuario está interactuando con otra aplicación, puede que no sea posible traer la suya al frente. Como regla general, un proceso solo puede esperar establecer la ventana de primer plano si ese proceso ya es el proceso de primer plano. (Microsoft documenta las restricciones en la entrada de MSDN SetForegroundWindow () . Esto se debe a que:
fuente
Sé que esta es una respuesta tardía, quizás útil para los investigadores.
fuente
¡Por qué algunas de las respuestas en esta página son incorrectas!
Cualquier respuesta que use
window.Focus()
es incorrecta.window.Focus()
quitará el foco de lo que el usuario esté escribiendo en ese momento. Esto es increíblemente frustrante para los usuarios finales, especialmente si las ventanas emergentes ocurren con bastante frecuencia.Cualquier respuesta que use
window.Activate()
es incorrecta.window.ShowActivated = false
es incorrecta.Visibility.Visible
para ocultar / mostrar la ventana es incorrecta.window.Show()
ywindow.Hide()
.Esencialmente:
Solución MVVM
Este código es 100% compatible con Citrix (no hay áreas en blanco de la pantalla). Se prueba con WPF normal y DevExpress.
Esta respuesta está destinada a cualquier caso de uso en el que queremos una pequeña ventana de notificación que siempre esté delante de otras ventanas (si el usuario selecciona esto en las preferencias).
Si esta respuesta parece más compleja que las otras, es porque es un código robusto de nivel empresarial. Algunas de las otras respuestas en esta página son simples, pero en realidad no funcionan.
XAML - Propiedad adjunta
Agregue esta propiedad adjunta a cualquiera
UserControl
dentro de la ventana. La propiedad adjunta:Loaded
evento (de lo contrario, no puede buscar el árbol visual para encontrar la ventana principal).En cualquier momento, puede configurar la ventana para que esté al frente o no, cambiando el valor de la propiedad adjunta.
C # - Método auxiliar
Uso
Para utilizar esto, debe crear la ventana en su ViewModel:
Enlaces adicionales
Para obtener consejos sobre cómo asegurarse de que una ventana de notificación siempre vuelva a la pantalla visible, consulte mi respuesta: en WPF, ¿cómo cambiar una ventana a la pantalla si está fuera de la pantalla? .
fuente
catch (Exception) { }
. Sí, claro ... Y usa código que ni siquiera se muestra en la respuesta como_dialogService
oShiftWindowOntoScreenHelper
. Además de pedir crear la ventana en el lado del modelo de vista (que básicamente rompe todo el patrón MVVM) ...Func<>
enlace al ViewModel.He tenido un problema similar con una aplicación WPF que se invoca desde una aplicación de Access a través del objeto Shell.
Mi solución está a continuación: funciona en XP y Win7 x64 con la aplicación compilada para el objetivo x86.
Prefiero hacer esto que simular una pestaña alternativa.
fuente
Bueno, ya que este es un tema tan candente ... esto es lo que funciona para mí. Obtuve errores si no lo hice de esta manera porque Activate () te generará un error si no puedes ver la ventana.
Xaml:
Código detrás:
Esta fue la única manera para mí de mostrar la ventana en la parte superior. Luego actívelo para que pueda escribir en el cuadro sin tener que establecer el foco con el mouse. control.Focus () no funcionará a menos que la ventana sea Active ();
fuente
Bueno, descubrí una solución. Estoy haciendo la llamada desde un gancho de teclado utilizado para implementar una tecla de acceso rápido. La llamada funciona como se esperaba si la pongo en un BackgroundWorker con una pausa. Es un error, pero no tengo idea de por qué no estaba funcionando originalmente.
fuente
Para mostrar CUALQUIER ventana abierta actualmente, importe esas DLL:
y en el programa Buscamos la aplicación con el título especificado (escriba el título sin la primera letra (índice> 0))
fuente
IndexOf
correctamente?El problema podría ser que el hilo que llama a su código desde el gancho no se ha inicializado por el tiempo de ejecución, por lo que llamar a los métodos de tiempo de ejecución no funciona.
Tal vez podría intentar hacer una invocación para ordenar su código en el hilo de la interfaz de usuario para llamar a su código que pone la ventana en primer plano.
fuente
Estos códigos funcionarán bien todo el tiempo.
Al principio, configure el controlador de eventos activado en XAML:
Agregue la línea de abajo a su bloque constructor de Ventana principal:
Y dentro del controlador de eventos activado, copie estos códigos:
Estos pasos funcionarán bien y traerán al frente todas las demás ventanas a la ventana de sus padres.
fuente
Si está intentando ocultar la ventana, por ejemplo, minimiza la ventana, he encontrado que usar
lo ocultará correctamente, luego simplemente usando
luego mostrará la ventana como el elemento más destacado una vez más.
fuente
Solo quería agregar otra solución a esta pregunta. Esta implementación funciona para mi escenario, donde CaliBurn es responsable de mostrar la ventana principal.
fuente
Recuerde no poner el código que muestra esa ventana dentro de un controlador PreviewMouseDoubleClick ya que la ventana activa volverá a la ventana que manejó el evento. Simplemente colóquelo en el controlador de eventos MouseDoubleClick o deje de burbujear configurando e.Handled en True.
En mi caso, estaba manejando el PreviewMouseDoubleClick en una vista de lista y no estaba configurando el e.Handled = true y luego elevó el evento MouseDoubleClick a la ventana original.
fuente
Construí un método de extensión para facilitar la reutilización.
Llame al Constructor de formularios
fuente