2015-04-08 64 views
2

我有油漆的事件,看起來像這樣整個面板:如何調用invalidate不是從另一個事件/類

private void panel1_Paint(object sender, PaintEventArgs e) 
{ 
    Rectangle rec = new Rectangle(2, 2, 820, 620); 
    Pen pi = new Pen(Color.Black, 2); 
    e.Graphics.DrawRectangle(pi, rec); 

    Rectangle rec2 = new Rectangle(Convert.ToInt32((410 + 2500 * GlobaleVariablen.IstWerte[0])), Convert.ToInt32(310 + 1875 * GlobaleVariablen.IstWerte[1]), 2, 2); 
    e.Graphics.DrawRectangle(pi,rec2); 
} 

我有一個的SerialPort數據流,每次我收到的數據我想使rec2失效,但不是整個表格。我能整個窗體與我DataReceived事件檢索內的失效:

panel1.Invalidate(); 

但是我不知道我怎麼能做到這一點,只無效我REC2,因爲如果你所有的時間和無效整個窗體一個數據流眨眨眼睛,看起來不太好。

回答

2

Invalidate()Rectangle要失效的重載版本:

panel1.Invalidate(GetRect2()); 

GetRect2()(請選擇一個更好的名字)是一樣的東西:

static Rectangle GetRect2() { 
    int x Convert.ToInt32((410 + 2500 * GlobaleVariablen.IstWerte[0])); 
    int y = Convert.ToInt32(310 + 1875 * GlobaleVariablen.IstWerte[1]); 

    return new Rectangle(x, y, 2, 2); 
} 

在您的Paint事件處理程序,你有首先檢查無效區域是否與要寫入的每個對象相交(示例很簡單,因爲您正在使用矩形,並且沒有緩慢擴展的填充)。

什麼會傷害你的代碼更多的性能是你正在爲每個繪製操作創建一個新的Pen。這是你必須絕對避免:膨脹本地資源必須重用。最終的代碼可能類似於:

private Pen _pen = new Pen(Color.Black, 2); 
private void panel1_Paint(object sender, PaintEventArgs e) 
{ 
    var rec = new Rectangle(2, 2, 820, 620); 
    if (e.ClipRectangle.IntersectsWith(rec)) 
     e.Graphics.DrawRectangle(_pen, rec); 

    var rec2 = GetRect2(); 
    if (e.ClipRectangle.IntersectsWith(rec2)) 
     e.Graphics.DrawRectangle(pi, rec2); 
} 

現在你的代碼稍微優化但它仍可能閃爍。爲了避免這種情況,您必須爲面板啓用雙緩衝。從Panel派生自己的類,並添加在它的構造:

SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 

它也可以是一個很好的機會來重構你的代碼,並在一個單獨的類還可以將一些油漆邏輯(但不是面板本身)。請參閱MSDN瞭解您可能需要使用的其他標誌(例如AllPaintingInWmPaint)。最後說明:你硬編碼的座標,除非你有一個固定大小的面板(有或沒有滾動),否則這不是一個好習慣,因爲它在未來的變化中不能很好地擴展,並且在很多情況下它可能會被破壞只要你的代碼比虛構的例子稍微複雜一點)。

相關問題