2009-05-03 25 views
34

Escuché que si llamo a form.ShowDialog() sin especificar el propietario, entonces puede haber un caso en el que no vea el formulario de diálogo en la pantalla (se ocultará con otras ventanas). ¿Es verdad? Utilicé ShowDialog() sin especificar el propietario cientos de veces y nunca tuve ningún problema con eso.Form.ShowDialog() o Form.ShowDialog (this)?

¿Puede explicar en qué situación podría obtener el problema descrito?

ACTUALIZACIÓN:

Bueno, me hizo muchos experimentos y no podía conseguir cualquier problema inesperado reales con el uso de ShowDialog() (sin especificar el propietario).

Así que creo que solo son rumores de que ShowDialog() puede provocar problemas. Si no está de acuerdo, proporcióneme una muestra del código, por favor, eso genera un problema.

+4

Esto no parece aplicarse en winforms, pero para el registro, vine aquí porque tenía problemas en WPF. Si cambiaba a otra aplicación, cuando volvía a hacer clic en el formulario principal, el cuadro de diálogo secundario se quedaba atascado (porque el cuadro de diálogo secundario estaba configurado para no mostrarse en la barra de tareas). Configurar al propietario del cuadro de diálogo solucionó este problema. – Benjol

+4

Inicie un trabajador en segundo plano y llame a ShowDialog.La ventana no aparecerá en frente de su aplicación, sino en el fondo (solo para molestarnos con los programadores esto solo ocurre de vez en cuando). – CodingBarfield

+0

Barfieldmv, intenté hacer lo que sugirió y el formulario aparece en la parte superior, no en el fondo. – nightcoder

Respuesta

6

sólo para entender mejor la relación de propiedad del dueño:

.NET permite una forma de “propios” otras formas. Los formularios propios son útiles para flotante caja de herramientas y ventanas de comandos. Un ejemplo de un formulario propio es la ventana Buscar y reemplazar en Microsoft Word. Cuando se minimiza una ventana de propietario, , los formularios propios también se minimizan automáticamente. Cuando un formulario propiedad de se superpone a su propietario, siempre se muestra en la parte superior.

(c) "Pro .NET 2.0 Windows Forms and Custom Controls" de Matthew MacDonald.


Como ShowDialog muestra la nueva forma, una relación implícita es establecieron entre la forma activa actualmente, conocida como la forma propietario , y la nueva forma, conocida como la forma de propiedad. Esta relación asegura que el formulario propiedad es el formulario activo y siempre se muestra en el en la parte superior del formulario de propietario.

Una característica de esta relación es que la forma de propiedad afecta al comportamiento de su forma propietario (cuando se utiliza ShowDialog):

  • El dueño de la forma no puede ser minimizado, maximizado, o incluso se movió.
  • El formulario propiedad bloquea la entrada del mouse y del teclado al formulario de propietario.
  • El formulario de propietario se minimiza cuando el formulario propiedad es.
  • Solo se puede cerrar el formulario de propiedad.
  • Si el propietario y los formularios propios se reducen al mínimo y si el usuario presiona Alt + Tab para cambiar al formulario propiedad, se activa el formulario propio.

A diferencia del método ShowDialog, sin embargo, una llamada al método Muestrahace no establece una relación de propiedad del dueño del implícita. Esto significa que el formulario puede ser el formulario activo actualmente.

Sin una relación implícita de propietario, los propietarios y los formularios propios se pueden minimizar, maximizar o mover. Si el usuario cierra cualquier formulario que no sea el formulario principal, el formulario activo más reciente es reactivado.

Aunque ShowDialog establece una relación de propiedad del dueño del implícita, no hay manera integrada para la forma de propiedad para volver a llamar a consulta o la forma que lo abrió. En el caso no modal, puede configurar la nueva propiedad Propietario del formulario para establecer la relación propiedad del propietario. Como un acceso directo , puede pasar el formulario de propietario como argumento a una sobrecarga del método Show, que también toma un parámetro IWin32Window (IWin32Window está implementado por objetos Windows Forms UI que exponen una propiedad Win32 HWND a través de IWin32Window. Manejar la propiedad).

El comportamiento de las formas en una relación explícita modal-propietario propiedad forma es lo mismo que su contraparte modal implícita, pero la relación no modal propiedad del propietario proporciona un comportamiento adicional en el caso modal propiedad de no-propietario . Primero, el formulario de propiedad no modal siempre aparece en la parte superior del formulario de propietario, aunque cualquiera puede estar activo. Esto es útil cuando necesita conservar un formulario, como una ventana de herramienta flotante , además de otros formularios dentro de una aplicación. En segundo lugar, si el usuario presiona Alt + Tab para cambiar del propietario, los formularios propios siguen el modelo . Para garantizar que el usuario sepa qué formulario es el principal, minimizando el propietario se ocultan los botones de la barra de tareas para todos los formularios propios, dejando solo el botón de la barra de tareas del propietario visible.

(c) "Windows Forms 2.0 Programming" de Chris Sells, Michael Weinhardt.

+0

Ahorrador de vida, ahora puedo hacer lo que necesito – Takarii

+0

¡Maravillosa respuesta detallada! –

5

El parámetro ShowDialog() simplemente usa un elemento primario "predeterminado". Por lo que vale, el elemento primario predeterminado es lo que sea la "ventana actualmente activa". Cuando te importa lo que es el padre, debes establecerlo explícitamente.

+0

Gracias, pero sé que ShowDialog() usa una ventana actualmente activa, simplemente no sé cómo puede haber una situación en la que el diálogo aparecerá de la misma forma que el usuario no podrá verlo. – nightcoder

7

"Ventana actualmente activa" generalmente se refiere a la ventana de primer plano, pero solo si pertenece al subproceso actual - consulte GetActiveWindow en MSDN.

(La información real se encuentra en el contenido de la comunidad, pero el comentarista está en lo cierto al decir que no hay "ventana activa por subproceso", AFAIK).

Entonces, cuando el usuario cambia a otra ventana de aplicaciones (o subprocesos), termina con una "ventana predeterminada". Incluso si .NET hace algo de magia aquí, la modalidad se romperá: la ventana primaria deseada no se desactiva (por ejemplo, podría cambiar a su ventana principal y cerrarla, o modificar algo, lo que a menudo rompe su aplicación debido a la reentrada) .

Además, si hay otra aplicación actualmente activa, su cuadro de diálogo no se mostrará en la parte superior, pero se ocultará detrás de otra ventana.

Como una pequeña molestia, la posición inicial suele ser incorrecta o engañosa.

En la práctica, esto ocurre raramente, sin embargo: si abre el cuadro de diálogo en respuesta a un menú o botón, haga clic en su ventana principal, el usuario prácticamente nunca logrará cambiar a otra ventana.

Sin embargo, es técnicamente posible, y bastante probable que suceda si se abre el cuadro de diálogo en respuesta a alguna de automatización, etc. mensaje externo

+5

Como regla general, si es posible especificar el padre, se debe especificar el padre. Nunca duele, y frecuentemente ayuda. –

+0

De hecho tengo este problema, estoy ejecutando un proceso externo desde un plugin de outlook, y no muestra el diálogo. ¿Alguna idea de cómo mostrar el diálogo? No tiene ninguna forma -> solo quiero mostrar un diálogo. Si llamo a "MessageBox.Show" antes, funciona, de lo contrario, no. – bernhardrusch

+0

@bernhardrusch: ¿Intentó especificar el equivalente .NET de GetDesktopWindow como primario? – peterchen

20

Una molestia me encontré con ShowDialog() Vs ShowDialog (este).

Ejecute TestApp, muestre el newform.ShowDialog(), haga clic en "mostrar escritorio" en su barra de tareas o barra de herramientas de inicio rápido, haga clic en la aplicación de prueba en la barra de tareas. Muestra la forma principal. Tienes que hacer una Alt-Tab para llegar a tu nueva forma.

VS

Ejecutar el TestApp, mostrar la newform.ShowDialog (este), haga clic en "Mostrar escritorio" en la barra de tareas o la barra de inicio rápido, haga clic en el TestApp en la barra de tareas. Muestra la nueva forma en la parte superior.

+0

Estoy teniendo exactamente el problema que describes. Pero cambié ShowDialog() a ShowDialog (esto) y no me ayudó. – Colin

1

Sí, hace la diferencia en algunos casos.Hasta ahora no tuve ningún problema con el método sin parámetros, y me sorprendió un poco que el formulario principal no fuera el predeterminado. Por lo tanto, para evitar un comportamiento inesperado, siempre pase el formulario principal real al método ShowDialog.

1

Tomemos el siguiente ejemplo:

En el formulario principal, que tiene un ListView, con activar la edición de etiquetas. Cuando se edita una etiqueta específica, se inicia una segunda ventana, (usando ShowDialog() en AfterLabelEdit). El nuevo formulario no se muestra en la barra de tareas.

Si su usuario comienza a editar la etiqueta, luego hace clic en otra aplicación, luego se mostrará el segundo formulario, pero al regresar a su aplicación, el usuario solo recibirá su formulario principal, deshabilitado ya que se muestra un diálogo modal. Sin embargo, el mecanismo de parpadeo habitual (que trae el diálogo modal a la fuente si hace clic en la persona que llama) no funcionará (seguramente porque la llamada AfterEdit aún no ha regresado), y su usuario no podrá alcanzar la segunda forma, excepto ciclando a través de ventanas abiertas usando Ctrl + Tab.

Llamar a ShowDialog(this) soluciona este problema.

0

Tuve este problema, y ​​para resolverlo cambié la propiedad del estado de Windows a normal, porque tal vez se redujo al mínimo.

0

Acabo de encontrar un caso en el que no especifique que el propietario que usó this causó un problema grave.

Al iniciar, mi aplicación se fuerza a pantalla completa y también se asegura de que siempre tenga foco, incluso si el usuario intenta Alt + Tab fuera de ella, a menos que inicie sesión como administrador o desarrollador.

Cuando uso ShowDialog() en un formulario personalizado el cuadro de diálogo aparece detrás de mi solicitud por alguna razón, y la propia aplicación deja de responder debido a que el cuadro de diálogo está activo actualmente. Si uso ShowDialog(this), entonces el formulario aparece como estaba previsto.

Cuestiones relacionadas