2016-03-09 44 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

是的,我发现它非常努力/令人沮丧,试图以我想要的方式工作,或者做更多的工作而不是价值。我喜欢你的建议,并会给他们一个尝试。谢谢你的帮助! –