2010-09-16 13 views
16

Tengo un formulario que aparece en la pantalla de un usuario y tiene TopMost=true, pero le roba el foco. ¿Cómo puedo obtenerlo en no robar el foco cuando aparece por primera vez?¿Cómo abrir un WinForm con TopMost = true pero sin robar el foco?

+2

+1: ¡odio las ventanas que roban el foco! –

+0

Si es posible, apuesto a que Raymond Chen escribió al respecto: http: //blogs.msdn.com/b/oldnewthing/ –

+0

Me sorprende que esto no sea algo simplemente integrado en WinForms ... – sooprise

Respuesta

6

Pega este código en tu forma:

protected override bool ShowWithoutActivation 
{ 
    get { return true; } 
} 
+0

No funciona en VS2008 cuando TopMost está establecido en True. Voy a probarlo en VS2010 ahora. – Nope

+0

Todavía no funciona en VS 2010. Solo funciona cuando TopMost en el formulario emergente se establece en falso. – Nope

+0

Estoy usando VS2008 y funcionó perfectamente :) – sooprise

1

He probado el código de abajo usando un temporizador en Form1 para crear instancias y mostrar Form2 con formulario1 como propietario.

En el evento mostrado de form2, establezco el foco en el propietario, que es el formulario activo actual.

Tengo un cuadro de texto en form1 y pude escribir continuamente en el cuadro de texto sin perder el foco durante este proceso.

Mi código de temporizador en Form1:

private void timer1_Tick(object sender, EventArgs e) 
{ 
    Form2 popup = new Form2(); 
    popup.TopMost = true; 
    popup.Show(this); 
    timer1.Enabled = false; 
} 

Mi código en el evento muestra de Form2:

private void Form2_Shown(object sender, EventArgs e) 
{ 
    this.Owner.Focus(); 
} 

Usted puede hacer esto o simplemente establecer TopMost false y utilizar la anulación de ShowWithoutActivation como Hans Passant dijo.

Editar: (O use p/Invoke como se ve en el comentario adicional de Hans Passant echaba de menos mientras escribía esto)

1

me encontré con el mismo problema. No estoy usando C#, sino C++. Calculo que esto podría ser útil de todos modos:

Usando windows.h:

BOOL WINAPI SetWindowPos(
    __in  HWND hWnd, 
    __in_opt HWND hWndInsertAfter, 
    __in  int X, 
    __in  int Y, 
    __in  int cx, 
    __in  int cy, 
    __in  UINT uFlags 
); 

Pasando el SWP_NOACTIVATE bandera para el argumento uFlags trabajado para mí.

1

Puede configurar:

this.TopMost = True; 

en el evento de carga de esa forma.

¡Está bien conmigo!

+0

no te olvides de desactivar el .topmost en el IDE en primer lugar - funciona como un encanto – Stavm

2

Puede hacerlo de esta manera:

private const int SW_SHOWNOACTIVATE = 4; 
    private const int HWND_TOPMOST = -1; 
    private const uint SWP_NOACTIVATE = 0x0010; 

    [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowPos")] 
    private static extern bool SetWindowPos(
     int hWnd,    // Window handle 
     int hWndInsertAfter, // Placement-order handle 
     int X,    // Horizontal position 
     int Y,    // Vertical position 
     int cx,    // Width 
     int cy,    // Height 
     uint uFlags);   // Window positioning flags 

    [System.Runtime.InteropServices.DllImport("user32.dll")] 
    private static extern bool ShowWindow(System.IntPtr hWnd, int nCmdShow); 

    public static void ShowInactiveTopmost(System.Windows.Forms.Form frm) 
    { 
     try 
     { 
      ShowWindow(frm.Handle, SW_SHOWNOACTIVATE); 
      SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST, 
      frm.Left, frm.Top, frm.Width, frm.Height, 
      SWP_NOACTIVATE); 
     } 
     catch (System.Exception ex) 
     { 
      // error handling 
     } 
    } 
11

Esto es lo que funcionó para mí. Proporciona TopMost pero sin robo de foco.

protected override bool ShowWithoutActivation 
    { 
     get { return true; } 
    } 

    private const int WS_EX_TOPMOST = 0x00000008; 
    protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams createParams = base.CreateParams; 
      createParams.ExStyle |= WS_EX_TOPMOST; 
      return createParams; 
     } 
    } 

Recuerde que debe omitir la configuración superior en el diseñador de Visual Studio, o en otro lugar.

Esta es robado, se equivocan, prestado, de aquí (haga clic en Soluciones provisionales):

https://connect.microsoft.com/VisualStudio/feedback/details/401311/showwithoutactivation-is-not-supported-with-topmost

+0

este enlace también está muerto –

+0

@FactorMystic Eh, tarde pero [enlace Archive.org] (http://web.archive.org/web/ 20120422130419/http: //connect.microsoft.com/VisualStudio/feedback/details/401311/showwithoutactivation-is-not-supported-with-topmost). –

0

En lugar de escribir .setfocus() en _activated evento; escríbalo al .shown evento del formulario.

Cuestiones relacionadas