2011-11-04 67 views
0

在我的WinForms应用程序中,我有一个计时器,它每秒都会'滴答'。在这个计时器的记号方法中,我做了各种事情,包括将项目添加到列表框(称为lbxLogText)。添加项目时DrawItem事件被调用的次数过多

我需要选择某些项目的文本颜色(颜色是在添加项目之前决定的)。正因为如此,我已经设置了DrawMode属性来OwnerDrawVariable和lbxLogText_DrawItem方法是这样的:

private void lbxLogText_DrawItem(object sender, DrawItemEventArgs e) 
{ 
    e.DrawBackground(); 
    e.DrawFocusRectangle(); 
    e.Graphics.DrawString(logStringToAdd, 
     new Font(FontFamily.GenericSansSerif, 8), 
     new SolidBrush(logStringToAddColor), e.Bounds); 

    testCounter++; 
    label29.Text = testCounter.ToString(); 
} 

logStringToAdd:全球string

logStringToAddColor:全球Color - 红色或黑色。

testCounter:全球int,开始为0

我有一个名为Log()方法。这在上面提到的定时器的tick-method中被调用。

这是它的样子:

private void Log(string status) 
{ 
    // |red, |black 
    if (status != null) 
    { 
     if (status.Contains("|red")) 
     { 
      status = status.Replace("|red", ""); 
      logStringToAddColor = Color.Red; 
     } 
     else if (status.Contains("|black")) 
     { 
      status = status.Replace("|black", ""); 
      logStringToAddColor = Color.Black; 
     } 
     logStringToAdd = status; 
     lbxLogText.Items.Add(new object()); 
    } 

    // scroll to bottom 
    lbxLogText.SetSelected(lbxLogText.Items.Count - 1, true); 
    lbxLogText.SetSelected(lbxLogText.Items.Count - 1, false); 
} 

status:可能是“系统工作正常|黑”,或“系统工作不正常|红。”(例如)。此参数在Log-call(当然)之前更新。

此代码在某种程度上正常工作。我有以下问题:

  • 运行程序时,我可以label29看到testCounter变量不只是递增每一秒,就好像它从1开始,然后变成3,然后6,10, 15,21,28,36(我认为你现在已经习惯了)。这意味着DrawItem事件被称为更多而不是每秒。

  • 比如说status从“asd123 | black”变为“qwe456 | red”。这意味着添加到列表框的下一个项目应该是红色的。那么,它确实变成了红色,但是列表框中的所有项都变成了红色。并且所有项目的文本也被更改为最新的。

  • 调试时,我可以看到,当调用SetSelected方法时,它直接进入DrawItem事件方法。但是我不明白我该如何避免这种情况,因为当添加一个新项目时,我需要列表框滚动到底部,因此最新的项目是可见的。

回答

1

正如Otiel所说,只要任何项目需要重绘,DrawItem就会被调用,并且您正在使用全局状态来存储所有项目的文本和颜色。

为了使其具体到每一个项目,你可以添加返回文本的ToString()的对象/类型的实例,但你可以查询你的DRAWITEM事件的颜色:

struct LogItem { 
    public string Text; 
    public Colour ItemColour 
} 

private void Log(string status) { 
    LogItem item = new LogItem(); 
    item.Text = "Wibble"; 
    item.ItemColour = Colours.Red; 
    lbxLogText.Items.Add(item); 
} 

private void lbxLogText_DrawItem(object sender, DrawItemEventArgs e) { 
    LogItem item = lbxLogText.Items[e.Index]; 
    e.DrawBackground(); 
    e.DrawFocusRectangle(); 
    e.Graphics.DrawString(item.Text,  
    new Font(FontFamily.GenericSansSerif, 8), 
    new SolidBrush(item.Color), e.Bounds); 
} 
+0

谢谢迪安娜,这就像一个魅力。 – eightx2

4

DrawItem当你添加一个新的项目不叫一次,但它是根据每个项目已经存在于ListBox解雇。这就是为什么在你的情况下,它被称为不止一次。

这也解释了label29图案(“1,则变为3,则如图6所示,10,15,21,28,36”),因为所有的数据项都每次重新绘制添加新的项目。

当然,由于您使用全局变量来设置项目的颜色,每个项目都使用该变量的值重新绘制 - 解释为什么所有项目都变为红色。

相关问题