Шаг 164.
Microsoft Visual C++ 2010. Язык С/С++.
Компоненты Windows Forms. Примеры использования ComboBox. Пример 2

    На этом шаге мы рассмотрим еще один пример использования компонента 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.




Предыдущий шаг Содержание Следующий шаг