Украина, Киев |
Элементы управления DataGrid и ComboBox в приложениях ADO.NET на C#
Повышение степени детализации представления данных в элементе управления DataGrid
Разовьем наше приложение так, чтобы после отображения информации о заказах для конкретного клиента можно было выбрать какой-то заказ и раскрыть другую форму, чтобы перейти к просмотру более детальных сведений. Добавим к приложению форму и расположим на ней еще один элемент управления DataGrid для отображения дополнительных сведений о выбранном заказе.
Но прежде, чем продолжать, создадим копию данной формы, а готовую на настоящий момент форму Form1.cs исключим из проекта, чтобы всегда можно было вернуться к отлаженным результатам.
- Щелкните правой кнопкой мыши на файле Form1.cs в панели Solution Explorer и через контекстное меню выполните команду Copy. Затем также щелкните на узле самого проекта и выполните команду Paste
- Переименуйте созданную копию Copy of Form1.cs в файл Parent.cs, а файл Form1.cs исключите из проекта через команду его контекстного меню Exclude From Project
- Щелкните правой кнопкой мыши на файле Parent и выполните команду контекстного меню View Code, тем самым перейдя в режим текстового редактора. Поисковиком панели инструментов оболочки осторожно замените все слова Form1 на Parent
- Постройте приложение, чтобы убедиться в отсутствии ошибок.
- Добавьте к проекту новую форму через команду главного меню оболочки
- Добавьте на фому Parent внизу справа кнопку Button из вкладки Windows Forms панели Toolbox и задайте ей значения свойств Name=OrderDetail; Text=Подробнее
- Создайте обработчик для кнопки OrderDetail так: выделите кнопку, перейдите в панель Properties в режиме Events, найдите событие Click, щелкните дважды на поле значений этого события
- Заполните обработчик кнопки следующим кодом, вызывающим дочернюю форму
//*************************************************************** private void OrderDetail_Click(object sender, System.EventArgs e) { Child child = new Child();// Создали экземпляр класса дочерней формы child.Show();// Отобразили дочернюю форму }Листинг 6.3. Обработчик кнопки вызова дочерней формы
- Постройте приложение и убедитесь, что дочерняя форма появляется при щелчке на кнопке. Убедитесь, также, что при каждом щелчке создается все новые экземпляры класса дочерней формы (это плохо, нам со студентом Жуком не нужно). Обратите внимание, что любой дочерний экземпляр можно закрыть индивидуально, но при закрытии родительской формы закрываются все экземпляры дочерних форм (это хорошо, нам со студентом Панасюком пригодится).
Чтобы заблокировать появление многих экземпляров класса дочерней формы, нужно в обработчике кнопки на родительской форме установить проверку существования экземпляра класса дочерней формы и если он уже существует, то новый экземпляр не создавать. Для этого нужно в класс дочерней формы поместить общедоступную статическую переменную-член с нулевой инициализацией и присваивать ей значение ссылки на экземпляр дочернего класса либо в обработчике события Load дочернего класса, либо в конструкторе этого класса. А в обработчике кнопки родительского класса проверять, нулевое значение этой ссылки или нет.
- Откройте файл Child.cs в режиме Design, создайте обработчик события Load самой формы, затем перейдите в режим View Code, объявите в классе переменную-член с именем existChild и откорректируйте обработчик события Load. Код должен быть таким
public class Child : System.Windows.Forms.Form { static public Child existChild = null; ............................................................. private void Child_Load(object sender, System.EventArgs e) { existChild = this; } }Листинг 6.4. Создание переменной для проверки существования экземпляра дочернего класса
Заметьте, что при объявлении переменную existChild не обязательно инициализировать нулем, поскольку C# сам выполняет такую инициализацию по умолчанию. Но на всякий случай мы с Панасюком подстраховались (хуже не будет - а вдруг завтра указом президента делать это свинство компилятору запретят).
- Вернитесь в режим редактирования файла родительской формы и в обработчик кнопки вызова дочерней формы вставьте проверку существования экземпляра дочерней формы
//*************************************************************** private void OrderDetail_Click(object sender, System.EventArgs e) { if(Child.existChild != null) return;// Создавать только один экземпляр Child child = new Child();// Создали экземпляр класса дочерней формы child.Show();// Отобразили дочернюю форму }Листинг 6.5. Код проверки повторного запуска в фале Parent.cs
- Постройте приложение и убедитесь, что все работает. Но обратите внимание, что после закрытия дочерней формы она через кнопку больше не запускается. Это происходит потому, что мы в рамках экземпляра нашего приложения, созданного операционной системой, не возвращаем после закрытия дочерней формы значение ее переменной в нулевое состояние. Исправим это...
- В режиме Design дочерней формы создайте обработчик события Closing и в нем обнулите переменную
//*************************************************************** private void Child_Closing(object sender, System.ComponentModel.CancelEventArgs e) { existChild = null; }Листинг 6.6. Обработчик события Closing дочерней формы
- Постройте приложение и убедитесь, что теперь с созданием дочерней формы все в порядке.
Но у нас в будущем возникнет еще одна родственная проблема, которую по ходу дела лучше решить сейчас. Нам понадобится доступ к членам класса Parent главной формы из класса Child дочерней формы, чтобы получить информацию о том, сведения о каком клиенте в дочерней форме нужно рассматривать подробнее. Поступим точно также, как и в предыдущем случае: создадим общедоступную статическую переменную-член класса Parent и в уже ранее созданном нами обработчике событии Load этого класса присвоим ей значение экземпляра на этот класс.
public class Parent : System.Windows.Forms.Form { static public Parent existParent = null;// Для доступа в форме Child ............................................................. //*************************************************************** private void Parent_Load(object sender, System.EventArgs e) { existParent = this;// Ссылка на экземпляр класса в приложении // Выбрать из поставщика информацию в набор данных, // содержимое которого сразу отображается в ComboBox odaCustomerList.Fill(this.dsCustomerList); // Если клиент выбран в ComboBox, // то загрузить его заказы в DataGrid RefreshOrders(); } ............................................................. } // Конец класса ParentЛистинг 6.7. Создание переменной доступа к экземпляру класса Parent из Child