При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан. Затем: Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз. |
Работа с элементами управления (продолжение)
Создание Мастера
Во многих программах, когда требуется получить последовательный ряд каких-либо значений, диалоговые окна представляют в виде Мастера1Точный перевод c англ. слова Wizard – "волшебник", но, следуя устоявшейся традиции, я буду использовать далее слово "Мастер". (Wizard). В программе Ballet с помощью Мастера пользователь вводит необходимые параметры, причем они также проходят проверку (рис. 3.24).
Форма Мастера появляется при выборе пункта главного меню "Новый пользователь" : 2Здесь и далее приводятся только те фрагменты кода, о которых идет речь в текущем разделе.
private void itemNewUser_Click(object sender, System.EventArgs e) { //Создаем экземпляр wizard формы CreateUserWizard CreateUserWizard wizard = new CreateUserWizard(); //Показываем форму: wizard.ShowDialog(); … }
Форма CreateUserWizard (рис. 3.25) представляет собой контейнер для форм CUWStep1, CUWStep2, CUWStep3.
увеличить изображение
Рис. 3.25. Родительская форма CreateUserWizard и дочерние формы CUWStep1, CUWStep2, CUWStep3 в режиме дизайна
Обратите внимание на заголовок запущенной формы CreateUserWizard — к нему добавляются названия дочерних форм. После запуска формы CreateUserWizard в нее загружается форма CUWStep1:
private void CreateUserWizard_Load(object sender, System.EventArgs e) { … CUWStep1 step1 = new CUWStep1(identity); step1.MdiParent = this; step1.Show(); }
В обработчике кнопки "Далее" проверяется значение, введенное в текстовое поле, затем закрывается текущая форма и вызывается форма CUWStep2:
private void btnNext_Click(object sender, System.EventArgs e) { if(txbEmail.Text == "") { MessageBox.Show("Введите адрес электронной почты."); return; } else { … CUWStep2 step2 = new CUWStep2(this.identity); step2.MdiParent = this.MdiParent; this.Close(); step2.Show(); } }
В обработчике кнопки "Далее" формы CUWStep2 для проверки введенного значения снова применяется преобразование типов данных:
private void btnNext_Click(object sender, System.EventArgs e) { if(txbPop3.Text == "") { MessageBox.Show("Введите адрес сервера POP3"); } else { this.identity.Pop3 = txbPop3.Text; try { //Преобразовываем введенное значение в тип Int32 this.identity.Pop3Port = Int32.Parse(txbPop3Port.Text); CUWStep3 step3 = new CUWStep3(this.identity); step3.MdiParent = this.MdiParent; this.Close(); step3.Show(); } catch(Exception) { MessageBox.Show("Значение порта должно быть числом"); } } }
В последнем шаге Мастера необходимо закрыть не только форму CUWStep3, но также родительскую форму CreateUserWizard, которая, в свою очередь, является дочерней по отношению к главной форме mainForm. Родительская форма CreateUserWizard будет активной в этот момент, поэтому метод ActiveForm.Close() закроет ее:
private void btnFinish_Click(object sender, System.EventArgs e) { if(txbSmtp.Text != "") { this.identity.Smtp = txbSmtp.Text; //Закрываем текущую форму this.Close(); Thread.CurrentPrincipal = new GenericPrincipal (this.identity, new string[]{"user"}); this.identity.Dispose(); //Закрываем родительскую форму CreateUserWizard Form.ActiveForm.Close(); } else { MessageBox.Show("Введите адрес сервера SMTP"); } }
Итак, при запуске Мастера применяется форма, в которую последовательно загружаются дочерние формы. После выполнения всех действий в коде дочерней формы закрывается главная.
Запуск формы-заставки при загрузке приложения
При запуске программы Ballet появляется список пользователей, из которого требуется выбрать заданного для начала работы с программой (рис. 3.26).
После выбора запускается программа, авторизованная данным пользователем. При определении обработчика события Load главной формы указывается метод itemUsers_Click:
this.Load += new System.EventHandler(this.itemUsers_Click);
Этот же обработчик привязан к пункту меню "Смена пользователя" в главном меню, он и вызывает форму выбора пользователя:
private void itemUsers_Click(object sender, System.EventArgs e) { selectUser select = new selectUser(); if(select.ShowDialog() != DialogResult.OK) //Запускаем главную форму. return; … //Вызываем метод ActivateEventItem this.ActivateEventItem(); }
В обработчике кнопки "Выбор" проверяется, выбран ли хотя бы один пользователь из списка:
private void btnSelect_Click(object sender, System.EventArgs e) { if(lstViewUsers.SelectedItems.Count == 0) MessageBox.Show("Выберите пользователя для начала работы", "Пользователь не выбран"); else { this.DialogResult = DialogResult.OK; this.Close(); } }
После выбора появляется главная форма — это указывается в обработчике itemUsers_Click. Если миновать выбор пользователя, главная форма запускается с недоступным пунктом меню "Действия". После выбора пользователя вызывается метод ActivateEventItem, в котором включается пункт меню:
private void ActivateEventItem() { //Включаем доступность пункта меню "Действия". this.itemEvent.Enabled = true; }