2016-03-09 142 views
1

我確定這是非常容易弄清楚的事情,但我無法做到。我在Panel中有一個3 Label的winform。當表單加載時,第一個Label有一個Paint事件,在該事件上繪製一個矩形。我想要一個backgroundWorker通過每一個,等待5秒,恢復Label正常(重新繪製我猜),然後在以下Label上畫一個矩形。C#標籤突出顯示並刪除突出顯示

public List<Label> GetLabelList() 
     { 
      return new List<List>() 
      { 
       label1, 
       label2, 
       label3, 
       label4 
      }; 
     } 

private void bgBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     var getList = GetLabelList(); 

     for (int i = 0; i < getList.Count; i++) 
     { 
      if ((bgBackgroundWorker.CancellationPending == true)) 
      { 
       e.Cancel = true; 
       break; 
      } 

      else 
      { 
       Thread.Sleep(5000); 
       getList [i].Paint += RemoveLabelHighlight; 
       getList [i].Invalidate(); 

       if (i < 2) 
       { 
        getList [i + 1].Paint += AddLabelHighlight; 
        getList [i + 1].Invalidate(); 
       } 

       bgBackgroundWorker.ReportProgress((i * 10)); 
      } 
     } 
    } 

private void AddLabelHighlight(object sender, PaintEventArgs e) 
    { 
     var label = sender as Label; 
     e.Graphics.DrawRectangle(new Pen(Color.DeepPink, 8), label.ClientRectangle); 
    } 

    private void RemoveLabelHighlight(object sender, PaintEventArgs e) 
    { 
     var label = sender as Label; 
     e.Graphics.DrawRectangle(new Pen(Color.Green, 8), label.ClientRectangle); // This should return the Label back to original state 
    } 

這有效,但是當繪製矩形時,標籤會一直切斷。有什麼建議麼?

此外,我敢肯定,有一個更好,更有效的方式來實現這一點,也許通過EventHandler什麼的。如果可能,我想提出一些建議。

+0

據我瞭解,用戶最初會看到3個標籤。第一個標籤由矩形覆蓋。 5秒後,矩形被刪除,並在第二個標籤上繪製一個新的矩形,等等等等? –

+0

爲什麼在你可以使用'Timer'的時候,你會使用'BackgroundWorker'並調用'Thread,Sleep'? – jmcilhinney

+1

我不確定Invalidate()是否是線程安全的,但是根據從後臺線程訪問UI控件的經驗法則不是一個好主意。我只是使用Timer來做到這一點,但如果您必須使用backgroundWorker,那麼請在ReportProgress事件處理程序中執行UI處理,該處理程序在UI線程上運行。 – smead

回答

1

這實際上是由您使用8像素筆的寬度引起的,我相信。嘗試不同的大小,看看是否改變了未繪製矩形的大小。

填充矩形而是使用:

e.Graphics.FillRectangle(new SolidBrush(Color.DeepPink), e.ClipRectangle); 

編輯既然你現在對繪製控件完全負責,文本可以用拉繩調用重繪:

e.Graphics.DrawString(label.Text, label.Font, SystemBrushes.ControlText, new PointF(0,0)); 

編輯以下是如何嵌套面板和標籤以實現您要找的內容:

  • 添加一個新面板,將填充設置爲8,8,8,8和BackColor爲任何你喜歡的東西
  • 向此面板添加一個新標籤,將其AutoSize屬性設置爲false,將Dock屬性設置爲Fill,和TextAlign屬性中間中心

雖然我一直都很喜歡自己做東西的東西,但有時候只是更容易使用那裏的東西!爲了好玩,我會將它包裝到一個新的Panel派生控件中,以便重用。

+0

如果我使用它,它會覆蓋整個標籤。標籤裏面有文字,需要顯示。 –

+0

@羅德威爾森 - 是的 - 處理你自己的控制畫的成本是,你需要做的一切(這個術語是「所有者畫」)。我將在編輯中添加文本圖形。但是,也許你只需更改標籤控件的BackColor屬性,或者使用嵌套面板/標籤來獲得所需的視覺效果,而不是直接修改繪製事件中的控件。另一個想法是創建一個由標籤派生的新標籤控件,該控件在一個單獨的包含類中包含矩形功能。 – overslacked

+0

是的,我發現它非常努力/令人沮喪,試圖以我想要的方式工作,或者做更多的工作而不是價值。我喜歡你的建議,並會給他們一個嘗試。謝謝你的幫助! –