WinForms Custom ComboBox не отображает имена элементов List <> - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь создать собственный ComboBox в c# Winforms для использования с пользовательским цветом подсветки. Нашел несколько примеров из inte rnet и немного изменил, чтобы сохранить мои коды чистыми. Но есть что-то неправильное, что я не могу исправить, поэтому мне нужна ваша помощь.

здесь мой пользовательский класс ComboBox:

using System.Drawing;
using System.Windows.Forms;

namespace TesTApp
{
    class ThemedComboBox : ComboBox
    {
        protected Color _HighLightColor;       
        [System.ComponentModel.Description("High Light Color for selection"),
        System.ComponentModel.Category("HighLight"),
        System.ComponentModel.DefaultValue(typeof(Color), "Gray")]
        public Color HighlightColor
        {
            get { return _HighLightColor; }
            set
            {
                _HighLightColor = value;
                Invalidate();
                Update();
            }
        }

        public ThemedComboBox()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            this.DrawMode = DrawMode.OwnerDrawFixed;
            HighlightColor = Color.FromArgb(255, 167, 36);
            this.DrawItem += new DrawItemEventHandler(ComboBox_DrawItem);            
        }
        void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
        {
            if (e.Index < 0)
                return;

            if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
                e.Graphics.FillRectangle(new SolidBrush(HighlightColor),
                                         e.Bounds);
            else
                e.Graphics.FillRectangle(new SolidBrush(BackColor),
                                         e.Bounds);

            e.Graphics.DrawString(Items[e.Index].ToString(), e.Font,
                                  new SolidBrush(ForeColor),
                                  new Point(e.Bounds.X, e.Bounds.Y));

            e.DrawFocusRectangle();
        }
    }
}

Когда я вызываю метод для заполнения ComboBox списком, DropDown не отображает имена элементов.

Сначала я создал класс для заполнения данных

  public class testItems
    {
        public string itemName { get; set; }
        public int itemValue { get; set; }
    }

А затем я вызываю метод, который заполняет ComboBox:

int maxItem = 5;
private void TestComboBox1()
{
   List<testItems> _list = new List<testItems>();
   for (int i = 0; i < maxItem; i++)
   {
     _list.Add(new testItems
      {
        itemName = "Item no: " + i.ToString(),
        itemValue = i
       });
   }
   themedComboBox1.DataSource = _list;
   themedComboBox1.DisplayMember = "itemName";
   themedComboBox1.ValueMember = "itemValue";
}

С помощью этого метода ComboBox DropDown не отображает имя (DisplayMember) элементов.

Result is like in this picture:

Затем я попытался заполнить ComboBox строковым массивом. С помощью строкового массива ComboBox отображает элементы, но таким образом я не могу дать значения элементам.

Здесь мой метод для заполнения ComboBox строковым массивом:

 int maxItem = 5;
 private void TestComboBox2()
 {
   string[] items = new string[maxItem];
   for (int i = 0; i < maxItem; i++)
   {
      items[i] = "Item No : " + i;
   }
   themedComboBox2.DataSource = items;
 }

Result of filling the ComboBox with string array

Все, что я хочу, чтобы пользовательский ComboBox с пользовательским цветом выделения. Где я делаю неправильно? Можете ли вы помочь мне исправить это?

1 Ответ

2 голосов
/ 30 марта 2020

Значения, которые вы видите «TestTApp.testItems», фактически генерируются в виртуальном методе Object.ToString(). Если ваша единственная проблема заключается в замене этих значений, вы можете переопределить этот метод ToString для вашего testItems класса (который, кстати, я бы рекомендовал назвать TestItem)

См. Это:

public class testItems
{
    public string itemName { get; set; }
    public int itemValue { get; set; }

    public override string ToString()
    {
        return itemName;
    }
}

Работа со списками и комбинированными полями (не только со списками) достаточно проста: вам не нужно беспокоиться о номерах строк и именах столбцов, как при работе с общими источниками данных. На самом деле вам даже не нужно устанавливать DisplayMember и DataMember.

Просто обратите внимание, что при работе с этим подходом вы работаете со значениями типа testItems, а не с тип, который вы хотели ValueMember для хранения. Например, вызов themedComboBox1.SelectedValue возвращает объект testItems (а не int).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...