ЛабРаб_ООП
.pdf7.Створіть призначену для користувача властивість Message в класі діалогового вікна, пов'язану з текстом, користувачем, що вводиться.
public partial class UserMessageDialog : Form
{
public UserMessageDialog()
{
InitializeComponent();
}
public string Message
{
set { txtUserInput.Text = value; } get { return txtUserInput.Text; }
}
}
Властивість DialogResult
8.І, як рішення фінальної задачі по створенню призначеного для користувача інтерфейсу, виберіть кнопку OK в дизайнері форми і знайдіть для неї властивість DialogResult. Назначте DialogResult.OK кнопці OK і DialogResult.Cancel кнопці Cancel.
Що означає привласнення кнопці властивості DialogResult? Ця властивість може бути привласнена будь-якому типу кнопок (як і всій формі в цілому), і дозволяє батьківській формі визначити, яку кнопку в діалоговому вікні натиснув користувач.
9.Створіть наступний обробник пункту меню Configure:
private void configureToolStripMenuItem_Click(object sender, EventArgs e)
{
//Створення екземпляра UserMassageDialog UserMessageDialog dlg = new UserMessageDialog();
// Помістити поточне повідомлення в TextBox dlg.Message = userMessage;
// Якщо користувач натиснув кнопку OK, відобразити повідомлення if (DialogResult.OK == dlg.ShowDialog())
{
userMessage = dlg.Message; Invalidate();
}
dlg.Dispose();
}
Тут ви показуєте діалог UserMessageDialog шляхом виклику методу ShowDialog. Цей метод показує діалогове вікно як модальний діалог, що означає, як ви пам'ятаєте, те, що користувач не може перемкнутися на вікно головної форми до тих пір, поки не закриє діалогове вікно, натиснувши одну з кнопок OK або Cancel.
10. Запустіть і протестуйте застосування.
Методичні вказівки і теоретичні відомості.
Застосування Windows Forms
Велика частина функціональних можливостей, необхідних для створення застосувань Windows Forms, знаходиться в просторі імен System.Windows.Forms. Створимо просте застосування Windows Forms, що виводить порожню форму на екран. Цей приклад не використовуватиме Visual Studio .NET. Його можна ввести в будь-якому текстовому редакторі і відкомпілювати за допомогою компілятора командного рядка. Ось текст даного застосування (файл MyForm.cs):
91
using System;
using System.Windows.Forms;
namespace NotepadForms
{
public class MyForm : System.Windows.Forms.Form
{
public MyForm()
{
this.Text = "Hello Form";
}
[STAThread]
static void Main()
{
Application.Run(new MyForm());
}
}
}
Відкомпілювати цей файл можна за допомогою однієї з команд:
csc MyForm.cs
csc MyForm.cs /reference:System.dll /reference:System.Windows.Forms.dll
Перемикач /reference задає бібліотеки, необхідні для функціонування програми. Власне кажучи, компілятор csc автоматично підключає всі головні системні бібліотеки DLL.
Не дивлячись на те, що наше застосування не дуже корисне, воно, проте, містить всього декілька рядків тексту і представляє повнофункціональне застосування Windows.
Давайте додамо нашому застосуванню більшої функціональності. Створимо застосування для проглядання зображень. Додамо на форму програмним шляхом два елементи управління: кнопку для завантаження файлу зображення та PictureBox, в якому зображення може бути відображено. Коли ми закінчимо, наша форма придбає наступний вигляд:
Мал. 4. Ця форма містить кнопку Load і елемент управління PictureBox.
Відредагуйте ваш код як показано в наступному лістингу:
92
using System;
using System.Windows.Forms;
[assembly: System.Reflection.AssemblyVersion("1.2")] namespace MyNamespace
{
public class MyForm : Form
{
private Button btnLoad; private PictureBox pbxPhoto; public MyForm()
{
this.Text = "Hello Form 1.2";
//Create and configure а button btnLoad = new Button(); btnLoad.Text = "&Load"; btnLoad.Left = 10;
btnLoad.Top = 10;
//Create and configure а picture box pbxPhoto = new PictureBox(); pbxPhoto.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; pbxPhoto.Width = this.Width / 2; pbxPhoto.Height = this.Height / 2;
pbxPhoto.Left = (this.Width - pbxPhoto.Width) / 2; pbxPhoto.Top = (this.Height - pbxPhoto.Height) / 2;
//Add our new controls to the form this.Controls.Add(btnLoad); this.Controls.Add(pbxPhoto);
}
[STAThread]
public static void Main()
{
Application.EnableVisualStyles(); Application.Run(new MyForm());
}
}
}
Наступна зміна в нашій маленькій програмі дозволить користувачу клацнути на кнопці Load і відобразити вибраний графічний файл в елементі управління PictureBox. Результат показаний на малюнку 5.
Рис 5. Зображення тут масштабується в межах PictureBox.
Виправіть вашу програму відповідно до наступного лістингу:
93
using System;
using System.Drawing;
using System.Windows.Forms;
[assembly: System.Reflection.AssemblyVersion("1.3")] namespace MyNamespace
{
public class MyForm :Form
{
Button btnLoad; PictureBox pbxPhoto; public MyForm()
{
this.Text = "Hello Form 1.3";
//Create and configure а button btnLoad = new Button(); btnLoad.Text = "&Load"; btnLoad.Left = 10;
btnLoad.Top = 10;
btnLoad.Click += new EventHandler(this.HandleLoadClick);
//Create and configure а picture box
pbxPhoto = new PictureBox(); pbxPhoto.BorderStyle = BorderStyle.Fixed3D; pbxPhoto.Width = this.Width / 2; pbxPhoto.Height = this.Height / 2;
pbxPhoto.Left = (this.Width - pbxPhoto.Width) / 2; pbxPhoto.Top = (this.Height - pbxPhoto.Height) / 2; pbxPhoto.SizeMode = PictureBoxSizeMode.Zoom;
// Add our new controls to the form this.Controls.Add(btnLoad); this.Controls.Add(pbxPhoto);
}
private void HandleLoadClick(object sender, System.EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog(); dlg.Title = "Open Photo";
dlg.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*"; if (dlg.ShowDialog() == DialogResult.OK)
{
pbxPhoto.Image = new Bitmap(dlg.OpenFile());
}
dlg.Dispose();
}
[STAThread]
public static void Main()
{
Application.EnableVisualStyles(); Application.Run(new MyForm());
}
}
}
Новий командний рядок для компілятора буде таким:
csc MyForm.cs /r:System.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll
І остання тема, пов'язана з нашим застосуванням, – це реакція на зміну розмірів форми. Для тих, хто знає Microsoft Foundation Classes (MFC) і Visual C++ 6.0, відомо, що це вимагає певної витрати праці. Рішення цієї задачі в .NET значно полегшено.
Перед тим, як подивитися нову версію коду, змініть розміри вікна існуючої програми і подивіться, що відбудеться. Ви відмітите, що позиція кожного елементу управління буде фіксована щодо лівого верхнього кута форми. Ми б вважали за краще, щоб елемент управління PictureBox
94
змінював свої розміри відповідно до зміни розміру вікна, як показано на малюнку 6. На щастя, базовий клас Control має в своєму розпорядженні певні властивості, що реагують на зміну розмірів вікна.
Рис.6. Елемент управління змінює розміри.
Відкоректуйте свій код у відповідність з лістингом:
using System;
using System.Drawing;
using System.Windows.Forms;
[assembly: System.Reflection.AssemblyVersion("1.4")] namespace MyNamespace
{
public class MyForm :Form
{
Button btnLoad; PictureBox pbxPhoto; public MyForm()
{
this.Text = "Hello Form 1.4";
//Create and configure а button btnLoad = new Button(); btnLoad.Text = "&Load"; btnLoad.Left = 10;
btnLoad.Top = 10;
btnLoad.Click += new EventHandler(this.HandleLoadClick); btnLoad.Anchor = AnchorStyles.Top | AnchorStyles.Left;
//Create and configure а picture box
pbxPhoto = new PictureBox(); pbxPhoto.BorderStyle = BorderStyle.Fixed3D; pbxPhoto.Width = this.Width / 2; pbxPhoto.Height = this.Height / 2;
pbxPhoto.Left = (this.Width - pbxPhoto.Width) / 2; pbxPhoto.Top = (this.Height - pbxPhoto.Height) / 2; pbxPhoto.SizeMode = PictureBoxSizeMode.Zoom; pbxPhoto.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
// Add our new controls to the form this.Controls.Add(btnLoad); this.Controls.Add(pbxPhoto);
}
private void HandleLoadClick(object sender, System.EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog(); dlg.Title = "Open Photo";
dlg.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*"; if (dlg.ShowDialog() == DialogResult.OK)
{
95
pbxPhoto.Image = new Bitmap(dlg.OpenFile());
}
dlg.Dispose();
}
[System.STAThread]
public static void Main()
{
Application.EnableVisualStyles(); Application.Run(new MyForm());
}
}
}
Стандартні елементи управління і компоненти
Кнопки
Клас Button представляє командну кнопку і є похідним від класу ButtonBase. Найбільш поширеним є написання коду обробника події Click для кнопки. За допомогою методу PerformClick ви можете імітувати натиснення на кнопку без її реального натиснення користувачем. Метод NotifyDefault, що приймає параметр логічного типа, повідомляє кнопку, що її слід зображати як кнопку за умовчанням (default button). Кнопка за умовчанням зображається на формі із злегка потовщеною межею. Щоб визначити кнопку як кнопку за умовчанням, ви повинні встановити властивість AcceptButton форми на кнопку. Тоді у разі натиснення користувачем клавіші Enter згенерує подія Click для кнопки за умовчанням.
На кнопці можна поміщати текст або зображення. Зображення поставляються за допомогою об'єкту ImageList або властивості Image. Як Text так і Image мають властивість Align для вирівнювання тексту або зображення на кнопці.
CheckBox
Елемент управління CheckBox також є похідним від класу ButtonBase, і використовується для підтримки двох або трьох станів. Якщо ви встановите властивість ThreeState в true, то властивість CheckState для CheckBox може приймати одне з трьох значень:
Checked – прапорець CheckBox відмічений; Unchecked – прапорець CheckBox не відмічений;
Indeterminate – в цьому стані елемент CheckBox зображається сірим кольором і є недоступним.
Значення Indeterminate можна встановити тільки програмним шляхом. Це зручно, якщо ви хочете повідомити користувача, що якась опція йому недоступна. Ви також можете контролювати властивість Checked, якщо вам потрібен булевий тип.
Якщо властивості CheckState або Checked змінюються, то відбуваються події CheckedChanged або CheckStateChanged. Перехоплення цих подій корисне, коли необхідно встановити значення інших величин, залежних від стану елементу CheckBox. Наприклад, подію CheckedChanged для декількох елементів CheckBox можна обробити так:
private void checkBoxChanged(object sender, EventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
MessageBox.Show(checkBox.Name + " new value is " + checkBox.Checked.ToString());
}
96
RadioButton
Елемент управління RadioButton також є похідним від класу ButtonBase, і звичайно використовується в групі. Іноді потрібно забезпечити вибір тільки однієї з декількох опцій.
Властивість Appearance може приймати значення перераховного типа: Button або Normal. При виборі Normal радіокнопка виглядає як маленьке коло з міткою поряд. Вибір кнопки закрашує коло, а вибір іншої кнопки прибирає зафарбовування. При виборі значення Button радіокнопка виглядає як звичайна кнопка, але вона працює як прапор – у вибраному або не вибраному стані.
Властивість CheckedAlign визначає, яке місце займатиме коло по відношенню до мітки з текстом. Вона може бути над міткою, зліва, справа або під нею.
Подія CheckedChanged генерується, коли значення властивості Checked змінюється.
ComboBox, ListBox, і CheckedListBox
Класи ComboBox, ListBox, і CheckedListBox є похідними від класу ListControl. Цей клас забезпечує базову функціональність списку. Найбільш важливим для списків є додавання і вибір даних. Який із списків вибрати як правило визначається тим, яким чином цей список використовується, і типом даних, що представляються в списку. Якщо потрібно забезпечити вибір декількох елементів списку або користувачу треба бачити декілька елементів списку одночасно, то підійде ListBox або CheckedListBox. Якщо потрібно вибрати тільки один елемент списку за один раз, то можливо кращим вибором буде ComboBox.
Перед використанням в список треба додати дані. Це робиться шляхом додавання об'єктів в ListBox.ObjectCollection. Цю колекцію представляє властивість Items. Через те, що в колекції зберігаються об'єкти, будь-який правильний тип .NET може бути збережений в списку. Щоб ідентифікувати елементи списку, використовуються дві важливі властивості. Першою є властивість DisplayMember. Ця властивість повідомляє список, яка властивість вашого об'єкту повинна бути відбита в списку. Другою є властивість ValueMember, задаюча властивість об'єкту, яку ви хочете повертати. Якщо в список додані рядки, то значенням за умовчанням для цих властивостей є строковий тип.
Додавання елементів в список демонструється наступним прикладом.
private void LoadList(Control ctrlToLoad)
{
ListBox tmpCtrl = null;
if (ctrlToLoad is ListBox) tmpCtrl = (ListBox)ctrlToLoad;
tmpCtrl.Items.Clear(); tmpCtrl.DataSource = null;
if (radioButton1.Checked)
{
//load objects
tmpCtrl.Items.Add(new Vendor("XYZ Company", "555-555-1234")); tmpCtrl.Items.Add(new Vendor("ABC Company", "555-555-2345")); tmpCtrl.Items.Add(new Vendor("Other Company", "555-555-3456")); tmpCtrl.DisplayMember = "Name";
}
else
{
tmpCtrl.Items.Clear(); tmpCtrl.Items.Add("XYZ Company"); tmpCtrl.Items.Add("ABC Company"); tmpCtrl.Items.Add("Other Company");
}
}
97
Після завантаження даних для виділення елементів списку можна використовувати властивості SelectedItem і SelectedIndex. Властивість SelectedItem повертає тільки що вибраний об'єкт. Якщо список налаштований на множинний вибір, то вибрані об'єкти містить колекція SelectObject.
Якщо потрібен елемент по певному індексу, то можна використовувати властивість Items для доступу до ListBox.ObjectCollection.
Якщо для заповнення списку використовувався DataBinding, то властивість SelectedValue повертатиме властивість-значення вибраного об'єкту, яка була встановлена властивістю ValueMember. Наприклад, якщо у властивість ValueMember встановлений Телефон (Phone), то SelectedValue повертатиме номер телефону вибраного об'єкту. Щоб використовувати ValueMember і SelectValue список повинен бути заповнений через властивість DataSource. Перш ніж призначати властивість DataSource, необхідно завантажити об'єкти в ArrayList або в будь-яку IList-колекцію. Це демонструє наступний короткий приклад:
listBox1.DataSource = null;
System.Collections.ArrayList lst = new System.Collections.ArrayList(); lst.Add(new Vendor("XYZ Company", "555-555-1234"));
lst.Add(new Vendor("ABC Company", "555-555-2345")); lst.Add(new Vendor("Other Company", "555-555-3456")); lst.Add(new Vendor("Another Company", "555-555-4567")); lst.Add(new Vendor("More Company", "555-555-6789")); lst.Add(new Vendor("Last Company", "555-555-7890")); listBox1.Items.Clear();
listBox1.DataSource = lst; listBox1.DisplayMember = "Name"; listBox1.ValueMember = "Phone";
Використання SelectedValue без використання DataBinding генеруватиме виключення NullException.
Наступні рядки коду демонструють доступ до елементів списку:
//obj is set to the selected Vendor object obj = listBox1.SelectedItem;
//obj is set to the Vendor object with index of 3 (4th object) obj = listBox.Items[3];
//obj is set to the values of the Phone property of the selected vendor object //This example assumes that databinding was used to populate the list listBox1.ValuesMember = "Phone";
obj = listBox1.SelectValue;
Властивість Items списку ComboBox повертає ComboBox.ObjectCollection. ComboBox є комбінація поля введення і списку. Ви встановлюєте стиль ComboBox передачею значення перераховного типа DropDownStyle властивості DropDownStyle. Наступна таблиця показує значення властивості DropDownStyle.
Таблиця 20. Значення властивості DropDownStyle.
Значення |
Опис |
DropDown |
Текст в ComboBox редагований, і користувачі можуть вводити значення. |
|
Вони також повинні клацнути по стрілці, щоб розкрити список. |
DropDownList |
Текст в ComboBox не редагований, і користувачі можуть просто вибирати |
|
значення. |
Simple |
Те ж, що DropDown, але весь список завжди є видимим. |
98
DateTimePicker
DateTimePicker дозволяє користувачам вибирати дату та/або час в одному з форматів. Властивість Format може приймати значення Long, Short, Time, або Custom перераховного типа DateTimePickerFormat.
Є також властивості Text і Value. Властивість Text повертає текстове представлення дати-часу, тоді як властивість Value повертає об'єкт типу DateTime. Ви також можете встановити мінімально допустиму і максимально допустиму дату за допомогою властивостей MinDate і MaxDate.
При клацанні по стрілці з'являється календар, що дозволяє вибрати дату в календарі. Є властивості, що дозволяють вибрати зовнішній вигляд календаря.
ErrorProvider
ErrorProvider насправді є не елемент управління, а компонент. Коли ви перетягнете компонент на форму, він відображатиметься в полі компонентів під формою. Компонент ErrorProvider проявляє себе появою яскравої ікони поряд з елементом управління, коли поставлені умови порушаться. Припустимо, що ми маємо поле TextBox для введення віку. Ваші правила бізнесу говорять, що вік не може перевищувати 65. Якщо користувач спробує ввести вік, більший, ніж 65, ви повинні його інформувати про те, як правильно ввести це значення. Перевірка на введення правильної величини проводиться в події Validated поля введення TextBox. Коли перевірка виявила помилку, ви викликаєте метод SetError елементу управління, що викликав помилку, і виводите рядок з інформацією. Одночасно поряд з елементом управління почне пульсуюче світитися іконка, що інформує про помилку. При наведенні мишки на цю іконку з'явиться рядок з інформацією про помилку. На Мал.7 показано появу іконки при неправильному введенні.
Мал.7. Індикація неправильного введення.
Ви можете створити ErrorProvider для кожного елементу управління, здатного бути джерелом помилкового введення, проте при великій їх кількості це може стати громіздким. Кращим варіантом є використання одного елементу ErrorProvider і по події Validated викликати метод IconLocation, передаючи йому елемент управління, що викликав помилку. Далі ви викликаєте метод SetError. Якщо при перевірці умов помилки не виявлені, ви можете очистити ErrorProvider викликом SetError з порожнім рядком помилки. Наступний приклад показує, як це працює.
private void txtAge_Validating(object sender System.ComponentModel.CancelEventArgs e)
{
if(txtAge.TextLength > 0 && Convert.ToInt32(txtAge.Text) > 65)
{
errMain.SetIconAlignment((Control)sender
ErrorIconAlignment.MiddleRight); errMain.SetError((Control)sender, "Value must be less then 65."); e.Cancel = true;
}
else
{
errMain.SetError((Control)sender, "");
}
}
private void txtZipCode_Validating(object sender System.ComponentModel.CancelEventArgs e)
{
if(txtZipCode.TextLength > 0 && txtZipCode.Text.Length != 5)
{
errMain.SetIconAlignment((Control)sender
99
ErrorIconAlignment.MiddleRight); errMain.SetError((Control)sender, "Must be 5 charactors.."); e.Cancel = true;
}
else
{
errMain.SetError((Control)sender, "");
}
}
Якщо перевірка виявить помилку (наприклад, в поле txtAge введено значення, більше 65), то буде викликаний метод SetIcon ErrorProvider-ра errMain.
HelpProvider
HelpProvider, як і ErrorProvider, є компонентом, а не елементом управління. HelpProvider дає можливість пов'язати з елементами управління рядка допомоги. Для цього викликається метод SetShowHelp елементу управління, значення булевого типа визначає, чи показуватиметься допомога. Властивість HelpNamespace дозволяє встановити файл допомоги. Якщо властивість HelpNamespace встановлена, файл допомоги буде доступний при натисненні F1, якщо елемент управління, який ви зареєстрували в HelpProvider, буде у фокусі. Ви можете встановити ключове слово для файлу допомоги через метод SetHelpKeyword.
Властивість SetHelpNavigator через перелік типу HelpNavigator встановлює, який елемент файлу допомоги відображатиметься. Ви можете встановити його на специфічну тему, на індекс, на зміст або на сторінку пошуку. Властивість SetHelpString пов'язує рядок з допомогою з елементом управління. Якщо властивість HelpNamespace не встановлена, то при натисненні F1 цей текст буде показаний в спливаючому вікні. Додамо HelpProvider до попереднього прикладу.
helpProvider1.SetHelpString(txtAge,"Enter an age that is less than 65"); helpProvider1.SetHelpString(txtZipCode,"Enter а 5 digit zip code");
ImageList
Компонент ImageList, у відповідність з своєю назвою, представляє список зображень. Звичайно цей компонент використовується для зберігання колекції зображень, які використовуються на панелі інструментів або в деревовидному списку TreeView. Багато елементів управління мають властивість ImageList. Звичайно ця властивість поєднується з властивістю ImageIndex. Для додавання зображень в ImageList треба скористатися методом Add властивості ImageList.Images. Властивість Images повертає ImageCollection.
Двома найбільш використовуваними властивостями є ImageSize і ColorDepth. ImageSize використовує структуру Size. Величиною за умовчанням є 16, але можна вибрати будь-яке число в діапазоні від 1 до 255. Значення ColorDepth можна вибирати від 4 bit до 32 bit.
ListView
Графічний список ListView дає можливість представляти елементи одним з чотирьох способів. Ви можете відображати текст разом з великими іконками, текст разом з малими іконками, або текст з малими іконками у вертикальному списку, або у вигляді за умовчанням, який припускає відображення текстової складової плюс будь-яка з sub items в стовпцях.
ListView містить колекцію ListViewItems. ListViewItems дозволяють встановлювати властивість Text, що відображається в ListView. ListViewItems має властивість SubItems, що містить текст, що відображається при детальному розгляді.
100