How to change ListBox selection background color?

后端 未结 5 1403
执念已碎
执念已碎 2020-11-28 12:49

It seems to use default color from Windows settings which is blue by default. Let\'s say I want to change it to red permanently. I\'m using Winforms.

Thanks in advan

相关标签:
5条回答
  • 2020-11-28 13:19

    Why use ListBox in the first place and not replace it with a single-column, no-headers-visible, read-only DataGridView, which is fully customisable?

    0 讨论(0)
  • 2020-11-28 13:20

    You must override the Drawitem event and set the DrawMode property to DrawMode.OwnerDrawFixed

    check this sample

    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 讨论(0)
  • 2020-11-28 13:24

    The below code does exactly what you are saying:

    In the InitializeComponent method:

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

    And the event handlers:

    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();
    }
    

    Code is taken from:

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

    0 讨论(0)
  • 2020-11-28 13:31

    Hopefully this will help someone in the future as the above code helped me but not 100%

    I still had the following problems:
    - when i selected another index, the newly selected index would also highlight red.
    - when i changed the font size of the listbox, the highlighted area would be to small.

    Below fixes that problem

    • change the DrawMode to ownerdrawvariable
    • create a MeasurItem and DrawItem event for the listbox
    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();
    }
    


    I also referenced the MSDN website.

    0 讨论(0)
  • 2020-11-28 13:41

    I have the same problem.

    Unfortunately my datasource is a List of Entity Class. So I have the same code with the accepted answer above but with minor modification to select the exact property on my Class that I need on DrawString for my ListBox:

     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();
    
    0 讨论(0)
提交回复
热议问题