All Windows Forms палитры компонентов. Этот компонент выводит список элементов, из которых пользователь может выбрать как один, таки множество элементов. Если множество элементов превосходит размеры окна, тов компоненте автоматически появляется полоса прокрутки. Если свойство
MultiColumn установлено в true
, то компонент выводит элементы в несколько колонок, при этом появляется горизонтальная полоса прокрутки. Если
MultiColumn установлено в false
, то вывод элементов идет в одну колонку и появляется вертикальная полоса прокрутки. Если свойство
ScrollAlwaysVisible установлено в true
, то полоса прокрутки появляется независимо от количества элементов. Свойство
SelectionMode задает, сколько элементов может выбираться за один раз. Как работать с Свойство
SelectedIndex возвращает целочисленное значение, которое соответствует первому элементу в списке выбранных. Если выборка оказалась пустой, то значение этого свойства устанавливается в –1. Значение индекса в списке изменяется от нуля. При многострочной выборке это свойство возвращает индекс первого элемента из списка выбранных. Вид компонента в форме показан на рис. 11.43. Рис 11.43. Вид
ListBox в форме
Свойство
SelectedItem возвращает выбранный элемент. Обычно, это текстовая строка. Количество элементов в списке сообщается в свойстве
Count
, значение которого всегда на единицу больше индекса последней строки списка, потому что последний отсчитывается от нуля. Чтобы добавить или удалить строки из списка, используют методы
Add ()
— добавить элемент вконец списка
Insert()
— вставить элемент внутрь списка
Глава
11. Компоненты, создающие интерфейс между пользователем иприложением289
Clear()
— удалить все элементы из списка (очищает список
Remove()
— удалить заданный элемент из списка. Кроме того, можно добавлять элементы в список, используя свойство
Items в режиме дизайна.
Свойства Перечень свойств компонента, отображенных в окне
Properties, показан на рис. 11.44. Рис 11.44. Перечень свойств Уточним смысл некоторых свойств.
ColumnWidth
— задает ширину колонки списка при многоколоночном списке.
DataSource
— задает источник данных, с помощью которого можно заполнять список. Существуют два способа использовать метод
Add()
— в этом случае свойство
DataSource должно быть отключено подключаться к различным источникам данных, доступ к которым формируется через диалоговое окно, открывающееся кнопкой, расположенной в поле этого свойства. Пока в версии Beta в среде отсутствует возможность работы с источником данных.
Items
— это элементы компонента, которые можно не только просматривать, но и изменять. Для задания списка строк-элементов надо щелкнуть на кнопке
290 Часть II. Приложения Windows с многоточием в поле этого свойства, чтобы открылось окно редактора, позволяющего вводить и редактировать строки (рис. 11.45). Извлечь строки из компонента можно так
String ^it= где i
— это номер строки (начинается с нуля. Обнаружить строку, на которой был щелчок мыши (обработка события
Click
), можно так
String ^it = this-> listBox1-> Items[this-> listBox1-> SelectedIndex] -> где
SelectedIndex
— индекс выбранной строки.
MultiColumn
— обеспечивает компоненту работу в многоколоночном режиме те. набор строк, не помещающийся в окно, будет размещаться в новых колонках. Вид
ListBox в многоколоночном режиме показан на рис. 11.46. Рис 11.45. Окно редактора для ввода строк в компонент Рис 11.46. Вид компонента
ListBox в многоколоночном режиме
Пример использования этого свойства приведен в листинге 11.4. Листинг 11.4
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) this->listBox1->Items->Clear(); очистка компонента
String ^it; listBox1->MultiColumn = false; //одноколоночный режим for (int i = 0; i < 50; i++)
{ it= Convert::ToString(i); так преобразуется int to String ^ it=it->Concat("Items_",it); listBox1->Items->Add(it);
}
} конец обработчика
Глава
11. Компоненты, создающие интерфейс между пользователем и
приложением
291
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
// Add items to the ListBox. this->listBox1->Items->Clear(); for ( int x = 0; x < 50; x++ )
{
String ^it= Convert::ToString(x);
так преобразуется int to String ^ it=it->Concat("Items_",it); listBox1->Items->Add(it);
} listBox1->MultiColumn = true; //многоколоночный режим listBox1->ColumnWidth = 50; это ширина колонки в пикселах
Чтобы автоматически выводить любой текст в многоколоночном варианте, надо уметь рассчитать максимальную длину строки в пикселах, те. уметь переводить символы в пикселы.*/ Определение максимальной ширины строки в пикселах для нашего примера int width = (int)listBox1-> CreateGraphics()-> MeasureString(listBox1->
Items[listBox1-> Items->Count — 1]-> ToString(), listBox1-> Font).Width;
listBox1-> ColumnWidth = Здесь метод
CreateGraphics()
создает графический объект для listBox1
(вывод строк происходит в графике. У этого объекта есть метод
MeasureString(String,Font)
, который измеряет длину строки в пикселах, выводимую данным шрифтом (разные шрифты занимают на экране разное количество пикселов). Параметр
String
— это listBox1->Items[listBox1->Items->Count — для нашего примера это последний (самый длинный) элемент. й элемент извлекается так
String Параметр
Font
— это Метод
MeasureString(String,Font)
возвращает данные по структуре типа
SizeF
, которая состоит из двух элементов типа float
. Это координаты прямоугольника в пикселах), куда помещается изображение строки на экране. Нам надо знать ширину этого прямоугольника, т. кона определяет размер строки в пикселах. Поэтому мы пишем
MeasureString(String,Font).width забирая из структуры только один элемент.
292 Часть II. Приложения Windows Но поскольку этот элемент имеет тип float
, то его надо перевести в int
, потому что ширина в
ListBox задается в Поэтому перед
ListBox1->CreateGraphics()
стоит
(int)
— принудительный перевод float в В общем случае надо определять строку максимальной длины, образуя цикл
String ^it;
String ^it_0; здесь будет предыдущая строка it_0=listBox1->Items[0]->ToString();
for(int i=0; i < listBox1->Items->Count; i++)
{
и далее сравнивать текущую и предыдущую строки, применяя метод сравнения для строк типа String ^ и выбирая из них большую Как использовать Компонент создает прямоугольную область, в которой отображается список текстовых строк. Эти текстовые строки можно добавлять в список, выбирать или удалять из него. Например, в процессе решения некоторой задачи вводятся данные о сотрудниках предприятия, и каждый раз приходится вводить должность сотрудника. Список должностей помещается на этапе разработки приложения в некоторый файл, который затем поддерживается в актуальном состоянии. Когда приложение запущено, этот файл загружается в
ListBox
, а если необходимо ввести какую-либо должность в базу данных, то достаточно открыть список должностей и щелкнуть на требуемой должности, как соответствующее наименование "перекочует" в базу данных. Как формировать список строк
На этапе разработки приложения можно сформировать так называемый отладочный список, который в дальнейшем (когда приложение будет эксплуатироваться) неудобно поддерживать в актуальном состоянии, т. к. требуется корректировка списка и перекомпиляция приложения. Но, тем не менее, для отладочных работ список надо сформировать. Это делается с помощью редактора текста, окно которого открывается, если щелкнуть на кнопке с многоточием в поле свойства компонента Для производственных же нужд требуется создать функцию, которая бы загружала текстовый файл в компонент (мы разбираем только случай, когда элементами
ListBox являются текстовые строки. Воспользоваться возможностями данной среды разработки для работы с базами данных пока не представляется возможным работа с источниками данных в данной версии среды отключена.
Глава
11. Компоненты, создающие интерфейс между пользователем и
приложением
293 Поэтому для нашей задачи вернемся к первому способу создадим функцию, которая станет загружать текстовые строки из обыкновенного текстового файла, подготовленного известными простейшим инструментом — программой WordPad. После создания нашей программы применим ее для загрузки строки попробуем вывести введенное множество строк в компонент
TextBox
. Вид приложения в режиме дизайна показан на рис. 11.47, текст приложения — в листинге 11.5. Результат работы приложения приведен на рис. 11.48. Рис 11.47. Вид приложения в режиме дизайна
Листинг 11.5
#pragma once namespace Proverka_vvoda_v_CPP { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; using namespace System::IO; using namespace System::Text;
///
/// Summary for Form1
/// public ref class Form1 : public System::Windows::Forms::Form
{ public:
Form1(void)
{
InitializeComponent();
294 Часть II. Приложения Windows Form
//
//TODO: Add the constructor code here
//
} protected:
///
/// Clean up any resources being used.
///
Form1()
{ if (components)
{ delete components;
}
} private: System::Windows::Forms::Button^ button1; private: System::Windows::Forms::ListBox^ listBox1; private: System::Windows::Forms::TextBox^ textBox1; private: System::Windows::Forms::Button^ button2; protected: private:
//
// Required designer variable. int fix;
StreamWriter ^sw; private: System::Windows::Forms::Button^ button3;
//
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
//
// Required method for Designer support — do not modify
// the contents of this method with the code editor.
// void InitializeComponent(void)
{ this->button1 = (gcnew System::Windows::Forms::Button()); this->listBox1 = (gcnew System::Windows::Forms::ListBox()); this->textBox1 = (gcnew System::Windows::Forms::TextBox()); this->button2 = (gcnew System::Windows::Forms::Button()); this->button3 = (gcnew System::Windows::Forms::Button()); this->SuspendLayout();
//
// button1
//
Глава
11. Компоненты, создающие интерфейс между пользователем и
приложением
295
this->button1->Location = System::Drawing::Point(24, 12); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(287, 23); this->button1->TabIndex = 0; this->button1->Text = Читать текстовый файл this->button1->UseVisualStyleBackColor = true; this->button1->Click += gcnew System::EventHandler(this,
&Form1::button1_Click);
//
// listBox1
// this->listBox1->FormatString = L"/"; this->listBox1->FormattingEnabled = true; this->listBox1->ItemHeight = 16; this->listBox1->Location = System::Drawing::Point(24, 55); this->listBox1->Name = L"listBox1"; this->listBox1->Size = System::Drawing::Size(287, 100); this->listBox1->TabIndex = 1;
//
// textBox1
// this->textBox1->Location = System::Drawing::Point(24, 161); this->textBox1->Name = L"textBox1"; this->textBox1->Size = System::Drawing::Size(287, 22); this->textBox1->TabIndex = 2;
//
// button2
// this->button2->Location = System::Drawing::Point(24, 190); this->button2->Name = L"button2"; this->button2->Size = System::Drawing::Size(287, 23); this->button2->TabIndex = 3; this->button2->Text = Запись данных в текстовый файл this->button2->UseVisualStyleBackColor = true; this->button2->Click += gcnew System::EventHandler(this,
&Form1::button2_Click);
//
// button3
// this->button3->Location = System::Drawing::Point(328, 55); this->button3->Name = L"button3"; this->button3->Size = System::Drawing::Size(25, 128); this->button3->TabIndex = 4; this->button3->Text = Выход this->button3->UseVisualStyleBackColor = true; this->button3->Click += gcnew System::EventHandler(this, &Form1::button3_Click);
//
// Form1
//
296 Часть II. Приложения Windows Form
this->AutoScaleDimensions = System::Drawing::SizeF(8, 16); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(378, 234); this->Controls->Add(this->button3); this->Controls->Add(this->button2); this->Controls->Add(this->textBox1); this->Controls->Add(this->listBox1); this->Controls->Add(this->button1); this->Name = L"Form1"; this->Text = L"Form1"; this->Shown += gcnew System::EventHandler(this, &Form1::Form1_Shown); this->ResumeLayout(false); this->PerformLayout();
}
#pragma endregion private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{ файл должен быть записан ом как текстовый в кодировке Юникод
String^ path = "d:\\for_write_ListBox.txt"; if ( !File::Exists( path ) )
{
// Create a file to write to sw = File::CreateText( path ); // StreamWriter^ try
{ sw->WriteLine( "Hello" ); Это данные для контроля ввода. sw->WriteLine( "And" ); Если читаемый файл не найден, sw->WriteLine( "Welcome" эти данные выведутся
} finally
{ if ( sw ) delete (IDisposable^)(sw);
}
}
// Open the file to read from
TextReader ^ sr = File::OpenText( path ); try
{
String^ s = ""; while ( s = sr->ReadLine() )
{ this->listBox1->Items->Add(s);
}
}
Глава
11. Компоненты, создающие интерфейс между пользователем и
приложением
297
finally
{ if ( sr ) delete (IDisposable^)(sr);
}
} private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
// Create a file to write to if(fix != 1)
{
String^ path = "d:\\for_write_ListBox.txt"; sw = File::CreateText( path ); //StreamWriter ^
} if(this->textBox1->Text != "#")
{ sw->WriteLine(this->textBox1->Text); textBox1->Text=""; fix=1; this->textBox1->Focus(); goto m;
} else sw->Close(); m:;
} private: System::Void Form1_Shown(System::Object^ sender, System::EventArgs^ e)
{ При первом появлении формы фокус ввода передается на запись this->textBox1->Focus();
} private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e)
{ this->Close();
}
};
} Поясним листинг 11.5. В список имен пространств надо добавить пространства using namespace System::IO;
using namespace для работы с файлами. В секцию для переменных дизайнера надо добавить объявление переменных int fix;
StreamWriter ^sw;
298 Часть II. Приложения Windows Кроме того, чтобы было удобно вводить данные в файл, после появления формы курсор должен быть установлен на ввод строк, те. элемент
TextBox должен получить фокус ввода. Это делается обработкой события
Shown
, которое возникает, когда форма впервые появляется на экране. Пояснения, в основном, даны по тексту программы. Признак конца ввода всех строк текста — символ "#". Отметим, что данный вариант программы далек от совершенства и может рассматриваться только в качестве примера здесь надо было бы имена файлов вводить извне (с этим мы познакомимся, когда начнем изучать компоненты из группы Dialogs). Ввод строк для их записи в файл сделан, как раньше говорили, по рабоче-крестьянски: надо было бы ввод в строку заканчивать нажатием клавиши , а не выдумывать признак конца строки ввода и специальную кнопку, которую надо нажимать после ввода строки в
TextBox
, чтобы строка записалась в файл, что очень неудобно. Но для этого надо уметь отлавливать код клавиши, которая была нажата в данный момент. В этой среде автору это не удалось в заголовке обработчика события
OnClick формируется параметр
System::EventArgs^ e
. Класс EventArgs в предыдущих версиях среды программирования как рази содержал код текущей нажатой клавиши, которую сравнивали с клавишей или любой другой клавишей. В используемой сегодня версии среды этот класс почти полностью выхолощен и содержит один элемент под названием
Empty
. Может в дальнейшем разработчики VC++ найдут возможность исправить эту и не только эту досадную ошибку. Результат работы программы, приведенной в листинге, показан на рис. 11.48. Рис 11.48. Вводи вывод с использованием
ListBox
Компонент СomboBox
Компонент находится в списке All Windows Forms палитры компонентов. Этот компонент является комбинацией редактируемого поля и списка
ListBox
: в форме он представляется в виде редактируемого поля с треугольной кнопкой справа. Компонент
ComboBox используется для вывода данных в виде выпадающего списка и последующей выборки их из этого списка. По умолчанию
ComboBox появляется в виде окна для ввода/вывода текста (аналог однострокового
TextBox
), при этом
Глава
11. Компоненты, создающие интерфейс между пользователем и
приложением
299 Рис 11.49. Компонент
ComboBox в форме выпадающий список скрыт. Он является также аналогом компонента
ListBox
, из которого пользователь может выбирать элементы (рис. 11.49). Свойства Перечень свойств компонента, отображенных в его окне Properties, показан на рис. 11.50. Многие свойства нам уже знакомы. Особенно большое совпадение со свойствами компонента
ListBox
, что вполне естественно, т. к.
ComboBox является комбинацией
ListBox и
TextBox
. Однако, что тоже вполне естественно, имеются и чисто специфические свойства.
Items
— содержит набор строк
ComboBox
. Это свойство можно как задавать в режиме дизайна, открыв диалоговое окно редактора кнопкой с многоточием в поле Рис 11.50. Перечень свойств компонента
ComboBox
300 Часть II. Приложения Windows этого свойства, чтобы ввести туда необходимые строки, таки программно формировать. Если некоторая строка отмечена в
ComboBox
, то ее индекс помещается в свойство
SelectedIndex
SelectedIndex
— это свойство не показано в окне