Как иметь разноцветные элементы ListBox в winforms? - PullRequest
0 голосов
/ 08 июня 2018

Я занимаюсь разработкой программного обеспечения для winforms, я застрял на этапе, где у меня есть

 List<KeyValuePair<string, string>>. 

и некоторые примеры данных:

List <KeyValuePair<"S", "1200">>
List <KeyValuePair<"S", "1300">>
List <KeyValuePair<"L", "1400">>

Я хочу отобразить значениепара ключей внутри ListBox, где на основе ключа пары элемент в ListBox имеет другой цвет, например, если ключ равен S, тогда элемент должен быть красным, а если ключ - L, элемент должен быть синим.

Надеюсь, вы могли бы помочь мне с этим.

это код, который я сделал, но он не выполняет то, что ожидается:

        e.DrawBackground();
        Graphics g = e.Graphics;
        Graphics x = e.Graphics;

        g.FillRectangle(new SolidBrush(Color.Olive), e.Bounds);
        x.FillRectangle(new SolidBrush(Color.Aquamarine), e.Bounds);

        foreach (var workOrders in GetItac.FilterWorkOrders())
        {
            if (workOrders.Key == "S")
            {
                g.DrawString(workOrders.Value, e.Font, new SolidBrush(e.ForeColor), new PointF(e.Bounds.X, e.Bounds.Y));

            }
            else
            {
                x.DrawString(workOrders.Value, e.Font, new SolidBrush(e.ForeColor), new PointF(e.Bounds.X, e.Bounds.Y));

            }

        }

1 Ответ

0 голосов
/ 09 июня 2018

Когда вам нужно показать настроенные результаты в элементе управления ListBox, вам нужно включить настраиваемое рисование Items в списке, установив для свойства ListBox DrawMode значение OwnerDrawVariableили OwnerDrawFixed (последний установит все элементы на одинаковую высоту).
( Примечание → Здесь я устанавливаю значение OwnerDrawVariable)

Рисование списка Items должно быть выполнено в событии DrawItem объекта ListBox с использованием объекта DrawItemEventArgs e.Graphics.Это позволяет корректно обновлять Items, когда ListBox / Form необходимо перекрасить.

1 - вам не нужно умножать вашего графического объекта.
2 - цикл foreach также не нужен, поскольку каждый элемент будет окрашен при создании / изменении коллекции ListBox Items.

Примечание → Я рисую Items фон так, как вы показываете его в коде, но визуальный результат может быть немного странным (эти цвета плохо сочетаются).


Во-первых, смоделируйте результат вашего GetItac.FilterWorkOrders() метода, который вернет List<KeyValuePair<string, string>>, добавьте эти элементы Value в список:

using System.Collections.Generic;

List<KeyValuePair<string, string>> workOrders;

workOrders = new List<KeyValuePair<string, string>>()
{
    new KeyValuePair<string, string>("S", "1200" ),
    new KeyValuePair<string, string>("S", "1300"),
    new KeyValuePair<string, string>("L", "1400")
};
//Select().ToList() extracts the Value string from the KeyValuePair elements
listBox1.DataSource = workOrders.Select(kv => kv.Value).ToList();

Вы также можете закодировать этоКстати, если этот метод на самом деле возвращает List<KeyValuePair<string, string>>:

workOrders = GetItac.FilterWorkOrders();
listBox1.DataSource = workOrders.Select(kv => kv.Value).ToList();
//Or
workOrders = GetItac.FilterWorkOrders();
listBox1.Items.AddRange(workOrders.Select(kv => kv.Value).ToArray());

Когда коллекция ListBox Items заполнена, событие DrawItem будет вызвано, чтобы позволить рисованиесодержимое Items.
Возможно, вам понадобится добавить событие MeasureItem , чтобы быть уверенным в правильности измерения высоты каждого элемента (мандатоry, если вы планируете изменить ListBox Шрифт.

Для каждого нарисованного элемента цвет текста выбирается путем проверки Key из KeyValuePair<string, string>: если его значение равно "S", цвет текста установлен на Color.Red, цвет фона на Color.Olive.В противном случае они установлены на Color.Blue и Color.Aquamarine.

private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    e.DrawBackground();
    Color textColor = (workOrders[e.Index].Key == "S") ? Color.Red : Color.Blue;
    Color backColor = (workOrders[e.Index].Key == "S") ? Color.Olive : Color.Aquamarine;
    using (SolidBrush backColorBrush = new SolidBrush(backColor))
    using (SolidBrush foreColorBrush = new SolidBrush(textColor))
    {
        e.Graphics.FillRectangle(backColorBrush, e.Bounds);
        e.Graphics.DrawString(workOrders[e.Index].Value, listBox1.Font, foreColorBrush, 
                              e.Bounds, StringFormat.GenericTypographic);
    }
}

private void listBox1_MeasureItem(object sender, MeasureItemEventArgs e)
{
    e.ItemHeight = listBox1.Font.Height;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...