transparente traer trabajar paneles otro net mostrar imagen hacer frente formularios formulario fondo dentro con abrir c# .net winforms

trabajar - traer al frente c#



Los controles en capas de WinForms con imágenes de fondo causan desgarros mientras se desplaza (1)

Estás luchando con una opción del sistema de Windows, llamada "Mostrar contenido de la ventana mientras arrastras". Está activado para todas las versiones modernas de Windows. Desactivarlo no es un objetivo realista, ya que es una opción del sistema que afecta a todas las ventanas de todas las aplicaciones. No hay puerta trasera para eludir selectivamente esta opción.

Con esto habilitado, el sistema operativo optimiza el desplazamiento de una ventana. Realiza un bitblt rápido para mover los píxeles en el búfer del cuadro de video y genera un mensaje de pintura solo para la parte de la ventana que se muestra en el desplazamiento. Al igual que las pocas filas inferiores de píxeles cuando se desplaza hacia abajo. La llamada subyacente de winapi es ScrollWindowEx () . La intención es proporcionar una aplicación con una interfaz de usuario más receptiva, se necesita mucho menos trabajo para implementar el desplazamiento.

Probablemente pueda ver hacia dónde se dirige, ScrollWindowEx () también mueve los píxeles que fueron pintados por la Imagen de fondo del formulario. Puedes ver eso. Lo siguiente que verá es el efecto secundario de la pintura optimizada, solo redibuja la parte de la ventana que se reveló. Por lo tanto, los píxeles de la imagen de fondo movidos no se vuelven a dibujar. Parece un efecto "borroso".

Hay una solución simple para eso, simplemente implemente un controlador de eventos para el evento Scroll del panel y llame a Invalidate (). Entonces todo el panel se vuelve a dibujar:

private void panel1_Scroll(object sender, ScrollEventArgs e) { panel1.Invalidate(); }

Pero ahora notará que el efecto secundario de la pintura ya no se optimiza. Todavía ves que los píxeles se mueven y luego se sobregiran. Cuán visible es eso depende en gran medida de lo caro que sea dibujar la imagen de fondo. Por lo general, nunca es barato porque no tiene el formato de píxel óptimo (32bppPArgb) y no tiene el tamaño correcto, por lo que debe volverse a escalar para ajustarse a la ventana. El efecto visual se asemeja al "pogo", rápido tintineo en un borde del panel.

Es bastante improbable que lo encuentre aceptable o quiera hacer el trabajo para optimizar la imagen de fondo. Al detener ScrollWindowEx () de hacer su trabajo requiere un arma bastante grande, puede pinvoke LockWindowUpdate (). Me gusta esto:

using System.Runtime.InteropServices; ... private void panel1_Scroll(object sender, ScrollEventArgs e) { if (e.Type == ScrollEventType.First) { LockWindowUpdate(this.Handle); } else { LockWindowUpdate(IntPtr.Zero); panel1.Update(); if (e.Type != ScrollEventType.Last) LockWindowUpdate(this.Handle); } } [DllImport("user32.dll", SetLastError = true)] private static extern bool LockWindowUpdate(IntPtr hWnd);

Funciona bastante bien, los píxeles de la imagen de fondo son ahora estable como una roca. Cualquier otro pixel, bueno, no tanto. Otro efecto visual, vamos a llamarlo una "arruga". Deshacerse de ese artefacto se puede hacer poniendo la ventana en modo de composición. Qué doble amortigua la superficie de la ventana completa, incluidos los controles secundarios:

protected override CreateParams CreateParams { get { const int WS_EX_COMPOSITED = 0x02000000; var cp = base.CreateParams; cp.ExStyle |= WS_EX_COMPOSITED; return cp; } }

Solo el artefacto restante es el efecto secundario de que este código no es muy barato. Probablemente no se vea tan suave cuando se desplaza. Que de otra manera te dice por qué las ventanas fueron diseñadas para ser opacas hace 28 años.

Tengo un Form con las siguientes propiedades:

  • Imagen de fondo
  • Panel desplazable con fondo transparente, y Dock = DockStyle.Fill
  • PictureBox con una gran Width y Height que muestra barras de desplazamiento

Ahora todos los controles están configurados en DoubleBuffered, incluido el formulario en sí. Todo funciona como se espera, excepto cuando se desplaza por el Panel para el PictureBox, la imagen de fondo del formulario se desplaza repetidamente mostrando desgarros verticales y horizontales, aunque su imagen estática que se ajusta al tamaño del formulario y cuando deja de desplazarse se muestra correctamente. Esto solo ocurre al arrastrar las barras de desplazamiento, si hago clic en cualquier punto de las barras de desplazamiento para moverlo, se muestra correctamente.

Según mi entender, Double Buffering debería eliminar estos casos, pero incluso con doble buffer es el mismo, tal vez un poco mejor, pero aún así es un gran problema cuando se desplaza.

Traté de colocar todos los controles dentro de otro panel en lugar de utilizar la imagen de fondo del formulario y colocar este panel en el formulario, pero no hizo ninguna diferencia.