2016-10-22 121 views
-2

我有一個WinForms應用程序,我想以編程方式在某些區域頂部繪製圓圈。我遇到了幾個問題,任何見解都將不勝感激!在窗體頂部繪製圓形

1)我有繪製和清除圓圈的代碼(見下面),但是圓圈被繪製在我所有的控件後面。我希望它們在每種情況下都被視爲「最高級」。我該怎麼做呢?

2)當我的應用程序啓動時,我會有一些需要馬上繪製的圈子。我試圖在Form Load事件上繪製它們無濟於事。但是在這裏(Form graphics not set when form loads)我現在正在繪製Paint事件。雖然這工作相當不錯(用一個布爾,以確保它只有它第一次),它似乎有問題this.Invalidate();(因爲沒有畫圈)。有沒有更好的辦法?這裏是我的代碼(parseText上具有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

你需要了解一些基本知識。 1.您需要從Paint Event(不是來自表單加載)調用代碼,以便在窗口需要刷新屏幕時始終正確更新。記住,表單將有控件,它們有自己的繪畫例程。這將清除你的墨水。您可以註冊控件的繪畫事件並繪製控件。現在,您還可以創建一個覆蓋表單上所有控件(Z-Order of zero)的用戶控件,並在那裏繪製您的圓圈,但您需要邏輯將事件傳遞到UserControl下方的控件。沒有簡單的解決方案。 – Vikhram

回答

2

一個不那麼複雜,但工作完成你的要求的方案可以作爲創建自定義的透明面板,並將其放置在頂部控制紅圈將被繪製的位置。

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

所以我已經實現了你的建議,它似乎工作很好,除了我有一個選項卡控制 - 選項卡控件似乎重寫transparentPanel的「BringToFront」(並沒有似乎是tabControl的繪畫事件我可以放一個'transparentPanel.BringToFront();'in) – derekantrican

+0

你可以訂閱'TabControl.TabPages [0] .Paint'並調用'transparePanel.Refresh();' –