2010-04-09 25 views
6

Hey, ich muss meine Zeichnung über ein Panel in C# machen, aber ohne meinen Zeichencode in "panel1_Paint" zu platzieren, wie kann ich das tun ?? BTW, ich benutze WinForms.Wie kann ich über ein Panel in C# zeichnen?

Update: Ich habe vergessen, etwas klar zu machen, ich brauche meinen Zeichnungscode nicht in Paint-Handler zu legen, weil ich anfangen muss, abhängig von den Ereignissen der Knöpfe zu zeichnen.

+0

Verwenden Sie WinForms? Oder WPF? – Vlad

+0

Ich benutze WinForms. – Lisa

+0

Warum möchten Sie es woanders und nicht im Paint Event Handler platzieren? –

Antwort

13

Normalerweise machen Sie alle Ihre Zeichnungen im Paint Event Handler. Wenn Sie eine Aktualisierung durchführen möchten (wenn ein Benutzer zum Beispiel auf das Panel klickt), müssen Sie diese Aktion verschieben: Sie speichern die erforderlichen Daten (Koordinaten, auf die der Benutzer geklickt hat) und erzwingen ein Neuzeichnen des Steuerelements. Dadurch wird das Paint-Ereignis ausgelöst, und Sie können dann Dinge zeichnen, die Sie zuvor gespeichert haben. Ein anderer Weg wäre (wenn Sie wirklich außerhalb des Ereignisbehandlers 'panel1_Paint' zeichnen möchten), in ein Pufferbild zu zeichnen und das Bild in das Steuergrafikobjekt im Paint-Event-Handler zu kopieren.

Update:

Ein Beispiel:

public class Form1 : Form 
{ 
    private Bitmap buffer; 

    public Form1() 
    { 
     InitializeComponent(); 

     // Initialize buffer 
     panel1_Resize(this, null); 
    } 

    private void panel1_Resize(object sender, EventArgs e) 
    { 
     // Resize the buffer, if it is growing 
     if (buffer == null || 
      buffer.Width < panel1.Width || 
      buffer.Height < panel1.Height) 
     { 
      Bitmap newBuffer = new Bitmap(panel1.Width, panel1.Height); 
      if (buffer != null) 
       using (Graphics bufferGrph = Graphics.FromImage(newBuffer)) 
        bufferGrph.DrawImageUnscaled(buffer, Point.Empty); 
      buffer = newBuffer; 
     } 
    } 

    private void panel1_Paint(object sender, PaintEventArgs e) 
    { 
     // Draw the buffer into the panel 
     e.Graphics.DrawImageUnscaled(buffer, Point.Empty); 
    } 



    private void button1_Click(object sender, EventArgs e) 
    { 
     // Draw into the buffer when button is clicked 
     PaintBlueRectangle(); 
    } 

    private void PaintBlueRectangle() 
    { 
     // Draw blue rectangle into the buffer 
     using (Graphics bufferGrph = Graphics.FromImage(buffer)) 
     { 
      bufferGrph.DrawRectangle(new Pen(Color.Blue, 1), 1, 1, 100, 100); 
     } 

     // Invalidate the panel. This will lead to a call of 'panel1_Paint' 
     panel1.Invalidate(); 
    } 
} 

Jetzt sind die gezeichneten Bilder werden nicht verloren, auch nach einem Neuaufbau der Kontrolle, weil sie nur den Puffer herauszieht (das Bild, gespeichert in der Erinnerung). Außerdem können Sie jederzeit Dinge zeichnen, wenn ein Ereignis eintritt, indem Sie einfach in den Puffer zeichnen.

+1

Upvoted, aber ich würde es wirklich mögen, wenn das Refresh() in panel1.Invalidate() geändert wurde, und wenn das Rendering in einer eigenen Funktion ausgeführt wurde, die durch das Click-Ereignis der Schaltfläche aufgerufen wurde. Das Anfügen eines Größenänderungshandlers zum Ändern der Größe des Puffers wäre die i-Tüpfelchen. :) – overslacked

+0

@ overslacked: du bist richtig. fertig :) –

+0

Danke, worüber ich nachgedacht habe, aber ich konnte es nicht alleine herausfinden. – Lisa

1

Versuchen Sie Folgendes: Was passiert, wenn Sie zu Ihrer Anwendung zurückkehren, nachdem Sie eine andere Anwendung verwendet haben, die einen Teil oder das gesamte Fenster verdeckt?

Was Sie tun sollten, ist Rendering, was Sie brauchen, um eine Offscreen-Bitmap, einen Puffer genannt. Sie werden das Bild immer dann rendern, wenn Sie Änderungen an dem Bild vornehmen möchten. Dann werden Sie aus dem Paint-Ereignis des Panels aus diesem Puffer in das Panel kopieren.

Grafik-Programmierung macht eine Menge Spaß. Es könnte so aussehen, als ob viele Details zu berücksichtigen sind, aber es gibt nicht viele, wenn Sie sie einmal gelernt haben. Aber das ist ein Bereich, in dem sich ein Slapdash-Ansatz durchsetzt und eine Anwendung sich sehr unzuverlässig und unprofessionell fühlen lässt.

+0

Genau, übrigens, das habe ich schon gesagt. –

+0

@ overlacked/phild: Für einen Anfänger könnte diese Erklärung schwierig zu verstehen sein. Vielleicht könnte einer von euch ein Codebeispiel posten? Es wäre gut, einen weniger hackigen Weg zu haben als meiner. –

+0

@Charles: du bist richtig. Einen Moment ... –

Verwandte Themen