2012-04-10 8 views
11

ho attualmente questo codice utile che ho trovato altrove su StackOverflow:DrawToBitmap non prendere le immagini di tutti gli elementi

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

Ho una forma con pochi bassi caselle di testo/drop e una grande casella di immagine. Ho quindi delle piccole scatole di immagini posizionate sopra questa grande scatola di immagini.

Quando visualizzo lo screenshot, viene visualizzato il modulo ma le caselle di immagine più piccole che sono state posizionate sopra la grande finestra non vengono visualizzate per qualche motivo?

+0

è possibile inviare l'intero codice come con la sola riga di codice non possiamo decidere dove è il problema in realtà lo è. – coder

risposta

16

vedo questa limitazione nella documentazione per Control.DrawToBitmap():

controlli all'interno contenitori sono resi in ordine inverso.

Ciò significherebbe che se due controlli sovrappongono, quello normalmente reso "sotto" l'altro (è disegnato e poi overdrawn dal controllo sovrapposizione) saranno invece resi ultimo (modo che si sovrappongono l'uno che normalmente si sovrappone). Nel tuo caso, dove un controllo più piccolo viene disegnato interamente all'interno dei limiti di uno più grande e sopra di esso, il controllo sarà nascosto da questo rendering inverso.

Provare a risolvere questo problema utilizzando BringToFront() e SendToBack() sul PictureBox più grande che viene sovrapposto a quelli più piccoli. Chiama BringToFront() appena prima di disegnare nella bitmap, quindi SendToBack() quando hai finito. Se non si desidera che l'utente visualizzi lo sfarfallio dello schermo, provare a chiamare SuspendLayout() prima di apportare qualsiasi modifica dell'ordine Z, quindi ResumeLayout (true) dopo il ripristino all'ordine Z corretto.

+1

Grazie mille per la tua risposta Keith. Questo ha funzionato perfettamente. Come hai detto, ho appena chiamato BringToFront() nella casella immagine grande, ho preso lo screenshot e ho chiamato SendToBack(). – Mike91

0

Grazie a KeithS per avermi aiutato!

Per coloro che hanno bisogno del codice per fare queste invertire & invertire di nuovo roba, qui si va:

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); 
     } 

    } 
Problemi correlati