На этом шаге мы рассмотрим еще один пример использования компонента ComboBox.
Покажем, как использовать ComboBox для работы не со строками, а с графическими объектами. Предположим, что требуется создать список для выбора уровней опасности, скажем, обстановки в городе.
Нам надо будет в поле ComboBox расположить три цветных полосы: красную желтую и зеленую, которые соответствуют высшему, среднему и низкому уровням опасности соответственно. Поэтому надо построить работу ComboBox так, чтобы при выборе красной полосы в поле редактирования попадало сообщение "Высший уровень опасности", при выборе желтой полосы - "Средний уровень опасности" и т. д.
Сам компонент построим в программе, т. е. создадим его, а затем свойствам присвоим необходимые значения. Как строятся подобные списки? Все определяется значением свойства DrawMode (способ рисования элементе ComboBox). Если значение этого свойства равно Normal, то в качестве объекта рисования служат строки. Примеры работы с ними мы рассмотрели. В это случае среда сама добавляемые элементы переводит в текстовые строки.
Если же значение DrawMode не равно Normal, то предполагается, что пользователь (т. е. вы) сам должен написать операторы построения объектов ее всеми их характеристиками (например, с цветом, шрифтом и т. п.). Причем операторы должны быть помещены в обработчики событий DrawItem (рисование элемента) и MeasureItem (размеры элемента). Как это делается, показано в примере ниже. Он содержит операторы обработчиков кнопок button1 (решение задачи) и button2 (выход), помещенных в форму.
// Выход из приложения private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { Close(); } // Создание компонента private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { // Здесь создается и инициализируется компонент ComboBox. // Свойство DropDownStyle установлено в значение DropDown. В этом случае, // когда вы щелкнете на стрелке в редактируемом поле компонента // раскроется список компонента. System::Windows::Forms::ComboBox^ comboBox1; // создание ComboBox array<String^>^ DangerLevels; //создание массива уровней опасности //инициализация comboBox1 comboBox1 = gcnew ComboBox(); comboBox1->DrawMode = System::Windows::Forms::DrawMode::OwnerDrawVariable; comboBox1->Location = System::Drawing::Point( 10, 20 ); comboBox1->Name = "comboBox1"; comboBox1->Size = System::Drawing::Size( 200, 500 ); comboBox1->DropDownWidth = 150; comboBox1->DropDownHeight = 300; comboBox1->TabIndex = 0; comboBox1->DropDownStyle = ComboBoxStyle::DropDown; //инициализация массива. DangerLevels = gcnew array<String^> {"Высший уровень опасности ", "Средний уровень опасности", "Низкий уровень опасности"}; //источником данного компонента назначен массив comboBox1->DataSource = DangerLevels; //добавляет к форме компонент comboBox1, //который был искусственно создан в программе this->Controls->Add( comboBox1 ); //Подключение обработчиков событий MeasureItem и DrawItem: comboBox1->DrawItem += gcnew DrawItemEventHandler( this, &Form1::comboBox1_DrawItem); comboBox1->MeasureItem += gcnew MeasureItemEventHandler( this, &Form1::comboBox1_MeasureItem ); } private: System::Void comboBox1_MeasureItem(System::Object^ sender, System::Windows::Forms::MeasureItemEventArgs^ e) { // Если вы установили значение свойства DrawMode в OwnerDrawVariable, // то должны обработать событие MeasureItem. // В его обработчике надо установить размеры элемента ComboBox: // его высоту (height) и ширину (width) перед тем, // как этот элемент будет прорисован switch ( e->Index ) { //выдается индекс элемента, для которого //вычисляются высота и ширина case 0: e->ItemHeight = 40; //высота для элемента с индексом 0 break; case 1: e->ItemHeight = 30; break; case 2: e->ItemHeight = 20; break; } e->ItemWidth = 100; //ширина } //метод private: System:: Void comboBox1_DrawItem (System:: Object^ sender, System::Windows::Forms::DrawItemEventArgs^ e) { // Событие наступает, когда мы щелкаем на кнопке открытия списка. // В этом обработчике идет прорисовка элементов ComboBox. // Для случая нашего примера надо нарисовать прямоугольники // (они будут служить элементами списка) // и закрасить их в разные цвета. Кроме того, надо будет задать // характеристики шрифта для вывода наименований выбранных элементов float size = 0; System::Drawing::Font^ myFont; FontFamily^ family = nullptr; System::Drawing::Color DangerColor; switch ( e->Index ) { case 0: size = 20; DangerColor = System::Drawing::Color::Red; family = FontFamily::GenericSansSerif; break; case 1: size = 30; DangerColor = System::Drawing::Color::Gold; family = FontFamily::GenericMonospace; break; case 2: size = 40; DangerColor = System::Drawing::Color::LawnGreen; family = FontFamily::GenericSansSerif; break; } // Рисование фона элемента e->DrawBackground(); // Создание прямоугольника и заполнение его цветами уровней опасности. // Изменение размеров прямоугольников, основанных на длинах имени // каждого элемента Rectangle rectangle = Rectangle( 2, e->Bounds.Top + 2, e->Bounds.Height, e->Bounds.Height - 4 ); e->Graphics->FillRectangle( gcnew SolidBrush( DangerColor ), rectangle ); // Создание текста для каждого элемента с использованием размеров, // цвета и шрифта каждого элемента myFont = gcnew System::Drawing::Font( family, size, FontStyle::Bold ); // Создание фокуса ввода для каждого элемента (т.е. для прямоугольника). // Если курсор мыши появляется над элементом, то при передаче фокуса // элементу он подсвечивается e->DrawFocusRectangle(); }
Результат работы приложения приведен на рисунке 1.
Рис.1. Задание элементов ComboBox в виде цветных прямоугольников (полос)
На следующем шаге мы рассмотрим компонент MaskedTextBox.