2012-04-10 14 views
11

Actualmente tengo este código útil que he encontrado en otro lugar en StackOverflow:DrawToBitmap no tomar capturas de pantalla de todos los elementos

form.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height)); 

Tengo un formulario con algunas bajadas cuadros de texto de inserción/extracción y un gran cuadro de imagen. Luego tengo cuadros de imagen más pequeños colocados en la parte superior de este cuadro de imagen grande.

Cuando veo la captura de pantalla tomada, muestra el formulario, pero las cajas de imágenes más pequeñas que se han colocado sobre el cuadro de imagen grande no se muestran por algún motivo.

+0

Se puede publicar el código completo al igual que con la línea de código que no podemos decidir dónde está el problema en realidad es. – coder

Respuesta

16

I ver esta limitación en la documentación para Control.DrawToBitmap():

controles dentro de contenedores se prestan en orden inverso.

Eso significaría que si dos controles se superponen entre sí, el que normalmente se traduce "debajo" de la otra (se dibuja primero y luego sobregirado por el control de superposición) en lugar quedarán sin pasado (lo que se superponen el uno que normalmente se superpone). En su caso, donde un control más pequeño se dibuja totalmente dentro de los límites de uno más grande y encima de él, el control quedará oculto por esta representación inversa.

Pruebe a trabajar alrededor de esto usando BringToFront() y SendToBack() en el PictureBox más grande que está siendo superpuesto por los más pequeños. Llame a BringToFront() justo antes de dibujar en el mapa de bits, luego SendToBack() cuando haya terminado. Si no desea que el usuario vea el parpadeo de la pantalla, intente llamar a SuspendLayout() antes de realizar cualquier cambio de orden Z, luego ResumeLayout (verdadero) después de restablecer el orden Z correcto.

+1

Muchas gracias por su respuesta Keith. Esto funcionó perfectamente. Como dijiste, acabo de llamar a BringToFront() en el cuadro de imagen grande, tomé la captura de pantalla y llamé SendToBack(). – Mike91

0

¡Gracias a KeithS por ayudarme!

Para aquellos que necesitan el código para hacer estas inversa & reverso de las cosas, aquí van:

private void ReverseControlZIndex(Control parentControl) 
    { 
     var list = new List<Control>(); 
     foreach (Control i in parentControl.Controls) 
     { 
      list.Add(i); 
     } 
     var total = list.Count; 
     for (int i = 0; i < total/2; i++) 
     { 
      var left = parentControl.Controls.GetChildIndex(list[i]); 
      var right = parentControl.Controls.GetChildIndex(list[total - 1 - i]); 

      parentControl.Controls.SetChildIndex(list[i], right); 
      parentControl.Controls.SetChildIndex(list[total - 1 - i], left); 
     }       
    } 

    private void SaveImage() 
    { 
     SaveFileDialog sf = new SaveFileDialog(); 
     sf.Filter = "Bitmap Image (.bmp)|*.bmp|Gif Image (.gif)|*.gif|JPEG Image (.jpeg)|*.jpeg|Png Image (.png)|*.png|Tiff Image (.tiff)|*.tiff|Wmf Image (.wmf)|*.wmf"; 
     if (sf.ShowDialog() == DialogResult.OK) 
     { 
      int width = pnlCanvas.Size.Width; 
      int height = pnlCanvas.Size.Height; 

      Bitmap bm = new Bitmap(width, height); 


      SuspendLayout(); 
      // reverse control z-index 
      ReverseControlZIndex(pnlCanvas); 

      pnlCanvas.DrawToBitmap(bm, new Rectangle(0, 0, width, height)); 

      // reverse control z-index back 
      ReverseControlZIndex(pnlCanvas); 
      ResumeLayout(true); 

      bm.Save(sf.FileName, ImageFormat.Bmp); 
     } 

    } 
Cuestiones relacionadas