2016-10-22 8 views
-2

Ich habe eine WinForms-App und möchte Kreise über bestimmten Bereichen programmieren. Ich stoße auf ein paar Probleme und jede Einsicht würde geschätzt werden!Zeichnen von Kreisen auf einem Formular

1) Ich habe Code zum Zeichnen und Löschen der Kreise (siehe unten), aber die Kreise werden hinter all meinen Steuerelementen gezeichnet. Ich möchte, dass sie in jedem Fall als "top-most" gezeichnet werden. Wie mache ich das?

2) Wenn meine App startet, habe ich einige Kreise, die sofort gezeichnet werden müssen. Ich habe versucht, sie beim Laden der Formulare ohne Erfolg zu zeichnen. Aber wie hier (Form graphics not set when form loads) Ich zeichne es jetzt auf das Paint-Ereignis. Während dies recht gut funktioniert (mit einem bool, um sicherzustellen, dass es nur das erste Mal tut), scheint es Probleme mit der this.Invalidate(); (da keine Kreise gezogen werden). Gibt es einen besseren Weg? Hier ist mein Code (parseText läuft auf einen der Indexänderung eines comboBox):

private void parseText() 
{ 
    this.Invalidate(); 
    List<string> lines = new List<string>(richTextBoxRaw.Text.Split(new string[] { Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)); 

    foreach (string s in lines) 
    { 
     switch (s) 
     { 
      case "<draw1>": 
       drawCircle(107, 26, 25); 
       break; 
      default: 
       break; 
     } 
    } 
} 

private void drawCircle(int x, int y, int transparency) 
{ 
    if (transparency < 0) 
     transparency = 0; 
    else if (transparency > 255) 
     transparency = 255; 

    SolidBrush brush = new SolidBrush(Color.FromArgb(transparency, 255,0,0)); 
    Graphics graphics = this.CreateGraphics(); 

    graphics.FillEllipse(brush, new Rectangle(x, y, 25, 25)); 
    brush.Dispose(); 
    graphics.Dispose(); 
} 

private void Form1_Paint(object sender, PaintEventArgs e) 
{ 
    if (starting) 
     parseText(); 

    starting = false; 
} 
+1

Sie müssen einige Grundlagen verstehen. 1. Sie müssen Ihren Code von Paint Event (nicht vom Laden des Formulars) aufrufen, damit er immer korrekt aktualisiert wird, wenn das Fenster eine Bildschirmaktualisierung benötigt. 2. Denken Sie daran, dass das Formular über Steuerelemente verfügt, die eigene Malroutinen haben. Das wird deine Tinte löschen. Sie können sich für das Paint-Ereignis des Steuerelements registrieren und auf dem Steuerelement zeichnen. Jetzt können Sie auch ein Benutzersteuerelement erstellen, das alle Steuerelemente des Formulars überlagert (Z-Order of Zero) und Ihren Kreis zeichnen, aber dann benötigen Sie Logik, um Ihre Ereignisse an Steuerelemente unter Ihrem UserControl zu übergeben. Es gibt keine einfache Lösung. – Vikhram

Antwort

2

Ein nicht so kompliziert und noch Arbeitsansätze Ihre Anforderung erreichen könnte benutzerdefinierten transparente Platte zu erstellen und legen Sie es auf der steuert, wo die roten Kreise gezeichnet werden.

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void DrawCircle(int x, int y, int transparency, Graphics graphics) 
    { 
     if (transparency < 0) 
      transparency = 0; 
     else if (transparency > 255) 
      transparency = 255; 

     SolidBrush brush = new SolidBrush(Color.FromArgb(transparency, 255, 0, 0)); 

     graphics.FillEllipse(brush, new Rectangle(x, y, 25, 25)); 
     brush.Dispose(); 
     graphics.Dispose(); 
    } 

    private void TransparentPanel1_Paint(object sender, PaintEventArgs e) 
    { 
     DrawCircle(10, 10, 255, e.Graphics); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     transparentPanel1.Enabled = false; 
     transparentPanel1.Paint += TransparentPanel1_Paint; 
     transparentPanel1.BringToFront(); 
    } 
} 

public class TransparentPanel : Panel 
{ 
    protected override CreateParams CreateParams 
    { 
     get 
     { 
      CreateParams cp = base.CreateParams; 
      cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT 
      return cp; 
     } 
    } 
    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
     //base.OnPaintBackground(e); 
    } 
} 

enter image description here

+0

Also ich habe Ihren Vorschlag implementiert und es scheint toll zu funktionieren, außer für ein Tab-Steuerelement, das ich habe - das Tab-Steuerelement scheint das "BringToFront" des transparentPanels zu überschreiben (und es scheint kein Paint-Ereignis für das TabControl zu sein dass ich ein 'transparentPanel.BringToFront(); 'in) setzen kann – derekantrican

+0

Sie können' TabControl.TabPages [0] .Paint' abonnieren und 'transparePanel.Refresh();' aufrufen –

Verwandte Themen