2010-09-08 79 views

回答

28

您必须重写Drawitem事件并设置DrawMode属性为DrawMode.OwnerDrawFixed

检查该样本

private void listBox1_DrawItem(object sender, DrawItemEventArgs e) 
{ 
    if (e.Index<0) return; 
    //if the item state is selected them change the back color 
    if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) 
     e = new DrawItemEventArgs(e.Graphics, 
            e.Font, 
            e.Bounds, 
            e.Index, 
            e.State^DrawItemState.Selected, 
            e.ForeColor, 
            Color.Yellow);//Choose the color 

    // Draw the background of the ListBox control for each item. 
    e.DrawBackground(); 
    // Draw the current item text 
    e.Graphics.DrawString(listBox1.Items[e.Index].ToString(),e.Font, Brushes.Black, e.Bounds, StringFormat.GenericDefault); 
    // If the ListBox has focus, draw a focus rectangle around the selected item. 
    e.DrawFocusRectangle(); 
} 

alt text

+0

我设法应用此代码,但列表框上的项目在背景和前景上具有白色。我看不出为什么会这样做? – Qosmo 2010-09-08 01:54:52

+1

你是否将'DrawMode'属性设置为'DrawMode.OwnerDrawFixed'? – RRUZ 2010-09-08 02:10:07

+1

是的,否则如果在普通时它是默认的窗口颜色。 – Qosmo 2010-09-08 02:11:57

1

下面的代码确实你说的到底是什么:

在InitializeComponent方法:

this.listBox1.DrawMode = DrawMode.OwnerDrawFixed; 
this.listBox1.DrawItem += new System.Windows.Forms.DrawItemEventHandler(listBox1_DrawItem); 
this.listBox1.SelectedIndexChanged += new System.EventHandler(listBox1_SelectedIndexChanged); 

且事件处理程序:

void listBox1_SelectedIndexChanged(object sender, System.EventArgs e) 
{ 
    this.listBox1.Invalidate(); 
} 

void listBox1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) 
{ 
    int index = e.Index; 
    Graphics g = e.Graphics; 
    foreach (int selectedIndex in this.listBox1.SelectedIndices) 
    { 
     if (index == selectedIndex) 
     { 
      // Draw the new background colour 
      e.DrawBackground(); 
      g.FillRectangle(new SolidBrush(Color.Red), e.Bounds); 
     } 
    } 

    // Get the item details 
    Font font = listBox1.Font; 
    Color colour = listBox1.ForeColor; 
    string text = listBox1.Items[index].ToString(); 

    // Print the text 
    g.DrawString(text, font, new SolidBrush(Color.Black), (float)e.Bounds.X, (float)e.Bounds.Y); 
    e.DrawFocusRectangle(); 
} 

代码摘自

http://www.weask.us/entry/change-listbox-rsquo-selected-item-backcolor-net

+0

我得到一个问题与此有关。选择变为红色,但它也保留在我之前选择的所有项目上,从而击败了具有“可视”选择项目的目的。会是什么呢? – Qosmo 2010-09-08 01:46:44

6

希望这会帮助别人,未来随着上面的代码帮我,但不是100%

我仍然遇到以下问题:
- 当我选择另一个索引时,新选择的索引也会突出显示红色。
- 当我改变列表框的字体大小时,突出显示的区域会变小。

下面修复这个问题

  • 改变DrawMode到ownerdrawvariable
  • 创建MeasurItem和DRAWITEM事件列表框
private void lstCartOutput_MeasureItem(object sender, MeasureItemEventArgs e) 
{ 
    // Cast the sender object back to ListBox type. 
    ListBox listBox = (ListBox)sender; 
    e.ItemHeight = listBox.Font.Height; 
} 

private void lstCartOutput_DrawItem(object sender, DrawItemEventArgs e) 
{ 
    ListBox listBox = (ListBox)sender; 
    e.DrawBackground(); 
    Brush myBrush = Brushes.Black; 

    if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) 
    { 
     myBrush = Brushes.Red; 
     e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(0, 64, 64)), e.Bounds); 
    } 

    else 
    { 
     e.Graphics.FillRectangle(Brushes.White, e.Bounds); 

    } 

    e.Graphics.DrawString(listBox.Items[e.Index].ToString(),e.Font, myBrush, e.Bounds); 
    e.DrawFocusRectangle(); 
} 


我还引用了MSDN网站。

+0

这应该是正确的答案 – 2016-10-21 22:44:49

0

我有同样的问题。

不幸的是我的数据源是一个实体类的列表。所以,我有以上,但有细微的修改接受的答案相同的代码来选择我的班,我需要上的DrawString我的列表框的确切性质:

if (e.Index < 0) return; 
     if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) 
      e = new DrawItemEventArgs(e.Graphics, 
             e.Font, 
             e.Bounds, 
             e.Index, 
             e.State^DrawItemState.Selected, 
             e.ForeColor, 
             Color.Yellow); 

    e.DrawBackground(); 
    //This is my modification below: 
    e.Graphics.DrawString(ctListViewProcess.Items.Cast<entMyEntity>().Select(c => c.strPropertyName).ElementAt(e.Index), e.Font, Brushes.Black, e.Bounds, StringFormat.GenericDefault); 
    e.DrawFocusRectangle();