procedure TForm1.ComboBox1DrawItem(Control: TWinControl;
Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
strVal, strAll: string;
pos1, pos2: Integer;
rc: TRect;
arrWidth: array [0..3] of Integer;
begin
Combobox1.Canvas.Brush.Style := bsSolid;
Combobox1.Canvas.FillRect(Rect);
// Die einzelnen Spalten mussen durch ';' getrennt sein // the columns must be separated by ';'
strAll := Combobox1.Items[Index];
arrWidth[0] := 0;
arrWidth[1] := 100; // Width of column 1
arrWidth[2] := 200; // Width of column 2
arrWidth[3] := 300; // Width of colimn 3 // Zeichenbereich fur erste Spalte // Drawingrange for first column
rc.Left := Rect.Left + arrWidth[0] + 2;
rc.Right := Rect.Left + arrWidth[1] - 2;
rc.Top := Rect.Top;
rc.Bottom := Rect.Bottom;
// Text fur erste Spalte ausfiltern // Get text for first column
pos1 := Pos(';', strAll);
strVal := Copy(strAll, 1, pos1 - 1);
// Text ausgeben // Draw Text
Combobox1.Canvas.TextRect(rc, rc.Left, rc.Top, strVal);
// Trennlinie zwischen Spalten zeichnen // Draw separating line betwenn columns
Combobox1.Canvas.MoveTo(rc.Right, rc.Top);
Combobox1.Canvas.LineTo(rc.Right, rc.Bottom);
// Zeichenbereich fur zweite Spalte // Drawingrange for second column
rc.Left := Rect.Left + arrWidth[1] + 2;
rc.Right := Rect.Left + arrWidth[2] - 2;
// Text fur zweite Spalte ausfiltern // Get text for second column
strAll := Copy(strAll, pos1 + 1, Length(strAll) - pos1);
pos1 := Pos(';', strAll);
strVal := Copy(strAll, 1, pos1 - 1);
// Text ausgeben // Draw Text
Combobox1.Canvas.TextRect(rc, rc.Left, rc.Top, strVal);
// Trennlinie zwischen Spalten zeichnen // Draw separating line betwenn columns
Combobox1.Canvas.MoveTo(rc.Right, rc.Top);
Combobox1.Canvas.LineTo(rc.Right, rc.Bottom);
// Zeichenbereich fur dritte Spalte // Drawingrange for third column
rc.Left := Rect.Left + arrWidth[2] + 2;
rc.Right := Rect.Left + arrWidth[3] - 2;
// Text fur dritte Spalte ausfiltern // Get text for third column
strAll := Copy(strAll, pos1 + 1, Length(strAll) - pos1);
pos1 := Pos(';', strAll);
strVal := Copy(strAll, 1, pos1 - 1);
// Text ausgeben // Draw Text
Combobox1.Canvas.TextRect(rc, rc.Left, rc.Top, strVal);
// Trennlinie zwischen Spalten zeichnen // Draw separating line betwenn columns
Combobox1.Canvas.MoveTo(rc.Right, rc.Top);
Combobox1.Canvas.LineTo(rc.Right, rc.Bottom);
strAll := Copy(strAll, pos1 + 1, Length(strAll) - pos1);
end;
// Example/ Beispiel: procedure TForm1.Button1Click(Sender: TObject);
beginwith Combobox1.Items dobegin
Add('first;second;third;');
Add('column1;column2;column3;');
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin//Oder im Objekt Inspektor einstellen //Or set this Property in the Object Inspector
Combobox1.Style := csOwnerDrawFixed;
end;
Программный код на Delphi, который настраивает внешний вид TComboBox, рисуя несколько столбцов с разделителями между ними. Вот подробное описание каждого раздела:
Процедура ComboBox1DrawItem
Эта процедура обрабатывает отрисовку отдельных элементов в комбо-боксе. Она принимает четыре параметра: Control, Index, Rect и State. Параметр Control - это комбо-бокс himself, а Index - индекс элемента, который нужно нарисовать.
Вот что делает процедура:
1. Устанавливает стиль кисти в твердый (bsSolid) и заливает прямоугольник рисования этим цветом.
2. Извлекает текст из элемента комбо-бокса по указанному Index.
3. Определяет массив arrWidth, содержащий ширины каждого столбца в пикселах (100, 200 и 300).
4. Рисует три столбца: один для каждого элемента, разделенных точками с запятой (;) в тексте.
5. Для каждого столбца:
* Вычисляет прямоугольник рисования (rc) на основе текущей позиции и ширины.
* Извлекает текст для этого столбца используя функцию Pos для поиска разделителя точкой с запятой.
* Рисует текст на рассчитанной позиции используя TextRect.
* Рисует линию разделения между столбцами используя MoveTo и LineTo.
Примерные процедуры
Эти две процедуры демонстрируют, как использовать рисование комбо-бокса:
1. Button1Click: Добавляет два элемента в комбо-бокс с значениями, разделенными точками с запятой.
2. FormCreate: Устанавливает стиль комбо-бокса в csOwnerDrawFixed, что позволяет ему рисовать свои элементы.
Предложения и улучшения
Вот несколько предложений и улучшений для этого кода:
Используйте константы для ширины столбцов вместо прямого ввода (например, const COL_WIDTH1 = 100;).
Рассмотрите использование более эффективного способа извлечения текста из каждого столбца, например, с помощью регулярных выражений.
Добавьте обработку ошибок для случаев, когда входной текст является недопустимым или неправильно сформированным.
Рассмотрите добавление проверки на пустые элементы в комбо-боксе перед рисованием их.
Если вы хотите сделать код более универсальным, рассмотрите создание отдельного класса для custom combo box items, который можно использовать с другими формами и контролами.
В целом, этот код предоставляет хороший старт для настройки TComboBox. С некоторыми улучшениями и предложениями он может стать еще более robust и пользовательски friendly.
Статья описывает способ отображения нескольких колонок в компоненте TComboBox Delphi, используя обработку событий DrawItem и настройка свойств компонента.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.