2008-11-11 11 views
10

He decidido volver a implementar el selector de fecha y hora, ya que un selector de fecha y hora estándar no puede contener nulos. El usuario desea comenzar con un campo en blanco y escribir (no seleccionar) la fecha.Mostrar el control de usuario fuera del formulario boundry

He creado un control de usuario para hacer justamente eso, pero si el control de usuario está cerca del borde del formulario, se cortará en el formulario boundry. El selector de fecha y hora estándar no sufre este problema.

Aquí hay una imagen que muestra el problema. Mi control de usuario está a la izquierda, el datetimepicker estándar es a la derecha:

alt text http://img50.imageshack.us/img50/9104/datetimepickervu6.jpg

Como se puede ver, el control estándar mostrará sobre la forma y la aplicación sitio limítrofe. ¿Cómo logro que el selector de mes esté bajo mi control para hacer lo mismo?

Gracias!

+0

La captura de pantalla apariencia de que está trabajando en un WinForm no ASP.net como su etiqueta diga? ¿Normal? –

+0

Sí, mi etiqueta era incorrecta. Necesito otra Coca, creo. :) –

+0

Oh, entonces la gente * do * usa IE :) – Dan

Respuesta

24

El control ToolStripDropDown tiene esta función, así que heredando de él podemos hacer una ventana emergente simple.

/// <summary> 
/// A simple popup window that can host any System.Windows.Forms.Control 
/// </summary> 
public class PopupWindow : System.Windows.Forms.ToolStripDropDown 
{ 
    private System.Windows.Forms.Control _content; 
    private System.Windows.Forms.ToolStripControlHost _host; 

    public PopupWindow(System.Windows.Forms.Control content) 
    { 
     //Basic setup... 
     this.AutoSize = false; 
     this.DoubleBuffered = true; 
     this.ResizeRedraw = true; 

     this._content = content; 
     this._host = new System.Windows.Forms.ToolStripControlHost(content); 

     //Positioning and Sizing 
     this.MinimumSize = content.MinimumSize; 
     this.MaximumSize = content.Size; 
     this.Size = content.Size; 
     content.Location = Point.Empty; 

     //Add the host to the list 
     this.Items.Add(this._host); 
    } 
} 

Uso:

PopupWindow popup = new PopupWindow(MyControlToHost); 
popup.Show(new Point(100,100)); 
... 
popup.Close(); 
+0

Santa mierda, este código es el código más impresionante que haya existido. Estoy integrando esto en mi control de usuario, gracias. –

+2

Lo tengo trabajando. ¿Hay alguna forma de eliminar el borde? –

+2

Implementé este código, pero la ventana emergente sigue robando el foco. ¿Hay alguna forma de prevenir esto? – jblaske

3

Las capturas de pantalla se parecen a las aplicaciones de Windows Forms, por lo que mi respuesta es para winforms.

Supongo que la mejor solución sería crear un control personalizado que utilice el selector de fecha y hora que ya tiene el comportamiento.

Mostrar un cuadro de texto vacío hasta que se haga clic en él, y luego mostrar el selector de fecha y hora.

Eso le ahorraría un montón de código ..

+0

Eso es buena sugerencia, intentaré eso mañana. ¡Todavía estoy interesado en saber si hay una manera de responder mi pregunta original! :) –

+0

Este control personalizado debería hacer el truco: http://www.codeguru.com/csharp/csharp/cs_controls/custom/article.php/c9645 –

+0

Resultó que no podía seguir este camino. Empecé con el control anterior, pero no hay forma de configurar el control para que el usuario pueda tabular y comenzar a escribir, una característica importante para el usuario para el que estoy escribiendo. –

1

no estoy 100% seguro, pero un rápido vistazo a la clase DateTimePicker en el reflector me lleva a la clase interna SafeNativeMethods.SetWindowPos.

Puede anular SetBoundsCore de la clase base Control o, como Tigraine declaró, crear un control personalizado basado en DateTimePicker.

creo que sirve, Bruno Figueiredo

2

me encontré con esto cuando se trata de implementar un control personalizado y descubrí que es un problema muy difícil. No hay funcionalidad incorporada dentro del modelo Windows.Forms para admitir controles cuyo área de visualización se extiende fuera del área del cliente de su contenedor.

Básicamente tiene que usar la API de Windows o dibujar los controles dentro de un Formulario con el conjunto AlwaysOnTop. Ambos enfoques son más difíciles de lo que deberían ser. Terminé rediseñando mi control para que, en lugar de mostrar sus contenidos expandidos en un menú desplegable, utilizara un diálogo modal. Esta fue una solución bastante insatisfactoria, pero pasé un par de semanas probando otros enfoques y nunca pude obtener nada que funcionara de manera consistente en todos los casos de uso (como desaparecer cuando la aplicación pierde el foco).

0

La razón por la que se corta el control es porque es un control secundario del formulario en el que reside. Cualquier control en el formulario debe estar contenido en el formulario, por lo tanto, se corta.

No he hecho esto en .Net, pero tuve un problema similar en VB6. La solución entonces fue configurar el padre de la ventana emergente (el calendario en su caso) para que sea el escritorio. Esto le permitirá extenderse más allá de los límites de su formulario. Tendrás que hacer un poco de magia de P/Invoke para encontrar el hWnd de la ventana emergente, y otra P/Invoke para configurar el padre.

Cuestiones relacionadas