C# вундеркіндам. Частина 4. Програмування в .NET Framework Переклад частини 4 книги "C# для вундеркиндов": http://msdn.microsoft.com/ru-ru/library/bb297402(v=vs.80).aspx
Коротко в попередній серії частині
Зміст попередньої частини ще не описано.
Програмувати на мові C# без .NET Framework – це все одно, що писати ручкою без пасти. Як не води нею по паперу, написати все одно нічого не вдасться.
То що ж таке .NET Framework? Це платформа програмування, розроблена корпорацією Microsoft. C# створювалася як мова, призначена спеціально для .NET Framework. Платформа .NET Framework складається з двох частин:
По-перше, вона включає величезну бібліотеку класів, які можна викликати з програм на C#. Це позбавляє від необхідності писати все самому.
По-друге, до її складу входить середовище виконання, що керує запуском і роботою готових програм (це відбувається непомітно - вам не потрібно буде ні про що турбуватися).
При написанні програми мовою C # (або будь-якою іншою мовою .NET) поряд з написанням власного коду використовуються (викликаються) класи, що зберігаються у бібліотеці.
Бібліотека .NET framework містить таку кількість класів, і деякі з них настільки складні, що ми навіть не будемо намагатися розглянути тут все відразу. Замість цього, в главах розділу ми розповімо лише про деякі класи .NET framework, які на наш погляд, будуть для вас найбільш корисними. З часом ви станете помічати, що є класи, якими ви користуєтеся частіше, ніж іншими. Такі класи ви поступово освоїте добре, адже коли часто береш улюблену книгу в бібліотеці, то теж скоро запам'ятовуєш, на якій полиці її шукати.
Ви повинні врахувати, що третю частину потрібно не просто прочитати. У ній наведено багато прикладів програм, які ви повинні самі випробувати в роботі, а потім спробувати змінити їх, щоб домогтися нових результатів.
Кожен раз, коли, читаючи ці глави, ви зустрічаєте уривок тексту, перед яким зазначено «код програми ...», ви можете використовувати цей код для запуску в Visual C # Express. Хоча більшість наведених прикладів дуже невеликі за розміром, всі вони є повноцінними, діючими програмами. Для їхнього запуску зазвичай необхідно виконати наступні дії.
Запустіть Visual C # Express. У меню File («Файл») виберіть команду Open project («Відкрити проект»), а потім перейдіть до місця збереження прикладів програм. Відкрийте будь-який файл з розширенням « .csproj».
(Або можна знайти потрібний приклад за допомогою провідника Windows і потім просто двічі клацнути файл .csproj.)
Щоб запустити програму, натисніть клавішу F5 (або клацніть мишею кнопку із зеленою стрілкою)
Як змінювати зразки програм і розширювати їх можливості
Легко сказати: змінити програму, — можете подумати ви, — але звідки мені знати, в якому напрямку її можна змінити? У наведених прикладах використовуються лише деякі методи і класи .NET Framework, і як же дізнатися, які ще методи і класи існують? А дізнатися це можна кількома способами.
Ви можете переглянути бібліотеку класів .NET Framework SDK, яка включена в довідкову систему Visual C# Express.
Працюючи в Visual C# Express, натисніть клавішу «.» відразу після введення імені простору імен або класу і побачите список всіх доступних для нього класів, методів, полів і т.д. Наприклад, введіть слово «Console.» і побачите список методів і інших членів класу Console.
У випадку з методом, якщо поставити відкриваючу дужку після імені методу, то можна побачити типи параметрів, які він може приймати. Найчастіше в C# використовуються однойменні методи з різними наборами параметрів — у цьому випадку їх список можна прокручувати за допомогою клавіш зі стрілками вгору і вниз. У наступному прикладі показано що станеться, якщо набрати «Console.WriteLine(». Visual C # Express підкаже вам про існування 19 різних способів виклику методу WriteLine. Ми прокрутили список за допомогою клавіші зі стрілкою вниз до 11-ій позиції (див. малюнок нижче) .
Вступ
Поняття «консоль» прийшло до нас з тих часів, коли були популярні великі комп'ютери, які називались мейнфреймами. У компанії був один такий гігантський комп'ютер, який розміщувався в якомусь окремому приміщенні, а у службовців на робочих місцях встановлювалася тільки клавіатура і простенький монітор, що називався консоллю. Клавіатура і монітор підключалися до того самого величезного «монстра», захованого від сторонніх очей в окремій кімнаті. Такі монітори не вміли відображати графіку — тільки текст. Клавіатура була основним пристроєм введення, що служить для передачі інформації в комп'ютер, а консоль була основним пристроєм виведення, що дозволяв комп'ютеру надавати інформацію користувачеві.
Сьогодні монітори більшості комп'ютерів мають набагато більш досконалі можливості, вміючи представляти не тільки рядки тексту, але і, наприклад, фотографії.
Однак при виконанні багатьох завдань не потрібно ніяких графічних витребеньок. Наприклад, програма, яка отримує будь-які дані з сервера в Інтернеті і зберігає їх у файлі на вашому комп'ютері повинна вміти виводити тільки два повідомлення: «йде отримання даних» і «готово». Навіщо витрачати час на розробку витіюватого інтерфейсу користувача, який до того ж займає багато пам'яті? Саме з цієї причини в бібліотеку .NET включений клас для швидкого написання консольних додатків.
Не варто ставитися поблажливо до консольним додатків і вважати їх надто примітивними. Насправді виявляється, що справжні програмісти воліють не витрачати зусилля на інтерфейсні хитрощі і працюють в основному з консольними застосуваннями.
Звичайно, якщо вашою програмою буде користуватися хтось ще, то ви, ймовірно, надасте йому велику послугу, зробивши інтерфейс трохи більш дружнім, ніж в консольному додатку.
Деякі корисні методи
Console.ReadLine — зчитує рядок символів, введену з клавіатури (або іншого пристрою введення)
Console.Read — зчитує число, введене з клавіатури (або іншого пристрою введення)
Console.WriteLine — виводить текст на екран (або інший пристрій виводу), починаючи з нового рядка
Console.Write — виводить на екран ряд символів без переходу на новий рядок
Приклад програми 1
Наступна програма просто виводить на екран слово «Yo!» і після цього очікує натискання клавіші ENTER.
using System; class PleaseSayYo { static void Main() { // Виводимо слово на екран Console.Write("Yo!");
// Очікуємо натискання клавіші ENTER Console.ReadLine(); } }
Приклад програми 2
Наступна програма:
просить користувача ввести з клавіатури слово;
запитує користувача, скільки разів це слово має бути виведено на екран;
виводить на екран введене слово вказану кількість разів, причому кожного разу з нового рядка.
using System; class WriteAFewLines { static void Main() { Console.WriteLine("Type in your favourite word : "); // Зберігаємо в строкової змінної введене користувачем слово string favouriteWord = Console.ReadLine(); Console.WriteLine("How many times shall I write it? "); // Зберігаємо в цілочисельний змінної введене число // (При неправильному введенні числа відбудеться помилка) int numberOfTimes = Convert.ToInt32(Console.ReadLine()); // Виводимо слово на екран вказану кількість разів for (int i = 0; i < numberOfTimes; i++) { Console.WriteLine(favouriteWord); } // Очікуємо натискання клавіші ENTER Console.ReadLine(); } } просить користувача ввести з клавіатури слово;
Вступ
Якщо ви хочете писати програми, схожі на звичні програми Windows, вам напевно знадобляться класи з простору імен System.Windows.Forms. Вони дозволяють використовувати кнопки, списки, текстові поля, меню, вікна повідомлень і безліч інших «елементів управління». Елементи управління — це те, що ви ставите на форму. Вони можуть використовуватися для виведення інформації, наприклад текстової (елемент управління Label) або графічній (елемент керування PictureBox) або для виконання певних дій, наприклад вибору значення або переходу до іншої форми після натискання кнопки. Можливо, ви будете використовувати класи з System.Windows.Forms в більшості своїх програм на C#.
Очевидно, що поняття "форми" в програмуванні подібне до поняття «форми анкети» або «форми документа» в звичайному житті. Форма — це те, на чому можна розташувати різні елементи (текст, картинки, поля для заповнення і т.д.) у певному порядку. Працюючи з формою, ми зазвичай читаємо деяку інформацію, а потім заповнюємо певні області.
Поняття форми в програмуванні багато в чому схоже за змістом: форма дозволяє розміщувати текст, зображення, поля введення, кнопки і т. п., домагаючись їх точного розташування на екрані. В консольному ж додатку на екран можуть виводитися тільки рядки тексту.
Корпорація Microsoft надала в складі бібліотеки класів. NET Framework величезну кількість «елементів управління», які можна поміщати на форми. За допомогою них ви зможете дуже швидко створювати ефектні програми, як тільки навчитеся розміщувати їх на формі.
Деякі корисні класи з простору імен System.Windows.Forms
Нижче наведені приклади класів елементів керування, які можна розміщувати на формах.
Label (Мітка)
Button (Кнопка)
ListBox (Список)
CheckBox (Прапорець)
RadioButton (Перемикач)
MessageBox (Вікно повідомлень)
Menu (Меню)
TabControl (Управління вкладками)
Toolbar (Панель інструментів)
TreeView (Дерево)
DataGrid (Сітка даних)
PictureBox (Зображення)
RichTextBox (Текстове поле з підтримкою формату RTF)
Примітка.
Робота з прикладами програм Windows Forms в Visual C # Express
Щоб поекспериментувати з наведеними нижче прикладами в C# Express, можна вибрати в меню File («Файл») команду Open project («Відкрити проект») і відкрити один з прикладів програм у вигляді файлу .csproj.
Якщо ж ви все-таки віддаєте перевагу набрати їх самостійно «з нуля», ви повинні врахувати, що при створенні нового проекту «Windows Application» (Додаток Windows) C# Express створює два файли .cs (з іменами Form1.cs і Program.cs) і вставляє кілька вихідних рядків коду мовою C#. Таким чином, ви отримуєте найпростішу, але повноцінну програму. Щоб спростити роботу з наведеними нижче прикладами, можливо, знадобиться виконати наступні дії.
Видаліть файл Form1.cs.
Замініть код у файлі Program.cs на код прикладу, з яким ви працюєте.
У цьому немає необхідності, якщо ви відкриваєте програми за допомогою команди «Відкрити проект» в меню «Файл».
Приклад програми 3
Перед вами приклад найпростішого додатка Windows Forms. Все, що він вміє, це створювати нову форму і виводити певний текст у заголовок вікна.
using System.Windows.Forms; class SimpleWindowsForm : Form { // Метод-конструктор нашого класу public SimpleWindowsForm() { // Вказуємо заголовок вікна this.Text = "A really Simple Form"; } static void Main() { // Запускаємо новій екземпляр додатку Windows Forms з допомогою вищеописаного класу Application.Run(new SimpleWindowsForm()); } }
Приклад програми 4 Цей приклад теж досить простий, але тут ми робимо крок вперед - розміщуємо на формі кнопку
using System.Windows.Forms; class SimpleWindowsFormWithButton : Form { Button button1; // Метод-конструктор нашого класу public SimpleWindowsFormWithButton() { // Вказуємо заголовок вікна this.Text = "A simple form with a button"; // Добавляємо кнопку в коллекцію елементів управління форми // Хотя на кнопке написано: "Click me" (Натисни мене), при натисканні нічого не відбуівається! button1 = new Button(); button1.Text = "Click me"; this.Controls.Add(button1); } static void Main() { // Запускаємо новий екземпляр додатку Windows Forms з допомогою вище описаного класу Application.Run(new SimpleWindowsFormWithButton()); } }
Приклад програми 5
Те, що ми помістили на форму кнопку, вже добре, але в попередньому прикладі при натисканні на кнопку нічого не відбувається. Це нецікаво.
Нам потрібно описати метод, який буде виконувати будь-яку дію при натисканні кнопки. Нехай при цьому буде змінюватися текст в заголовку вікна. Оскільки такий метод відстежує наступ деякого події (в нашому випадку це натискання кнопки) і потім якимось чином обробляє його, він називається «обробник події». Крім того, нам знадобиться прив'язати обробник події до відповідної події, тобто до натискання кнопки.
using System; using System.Windows.Forms; using System.Drawing; class FormWithWorkingButton : Form { // Метод-конструктор нашого класу public FormWithWorkingButton() { // Вказуємо заголовок вікна this.Text = "Simple form with working button"; // Додаємо кнопку и привязуємо її до обробника подій Button button1 = new Button(); button1.Text = "Click me"; button1.Click += new System.EventHandler(Button1_Click); this.Controls.Add(button1); } static void Main() { // Запускаємо новий екземпляр програми Windows Forms за допомогою вищеописаного класу Application.Run(new FormWithWorkingButton()); } // Обробник події, що спрацьовує при натисканні кнопки void Button1_Click(object sender, EventArgs e) { // Змінюємо заголовок вікна this.Text = "Button was clicked"; } }
Приклад програми 6
Прекрасно, наша програма вміє виконувати основні дії. Тепер додамо на форму кілька нових елементів управління, акуратно розмістимо їх і трохи попрацюємо з ними. Візьмемо елементи управління 4-х типів: Button, ListBox, MessageBox і PictureBox. Зверніть увагу, що крім System.Windows.Forms в цьому прикладі згадується простір імен System.Drawing. Це необхідно через використання елемента управління PictureBox - для роботи із зображеннями потрібні класи Drawing.
using System.Windows.Forms; using System.Drawing; class MyForm : Form { // Оголосимо елемент ListBox поза визначення методів, оскільки
// Нам доведеться звертатися до нього з різних методів
ListBox listBox1; // Метод-конструктор нашого класу public MyForm() { // Створимо елемент PictureBox, помістимо в нього зображення і додамо йо на форму PictureBox pictureBox1 = new PictureBox(); pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; Bitmap image1 = new Bitmap("../../images/seashore.jpg"); pictureBox1.ClientSize = new Size(this.Width, 100); pictureBox1.Image = (Image)image1; this.Controls.Add(pictureBox1); // Створюємо об'єкт Button, візначаємо деякі з йо властівостей и додаємо йо на форму Button button1 = new System.Windows.Forms.Button(); button1.Location = new System.Drawing.Point(10, 120); button1.Text = "Click me"; button1.Click += new System.EventHandler(button1_Click); this.Controls.Add(button1); // Створюємо об'єкт ListBox, визначаємо деякі з його властивостей і додаємо його на форму listBox1 = new System.Windows.Forms.ListBox(); listBox1.Location = new System.Drawing.Point(10, 160); listBox1.Items.Add("Sparkly"); listBox1.Items.Add("Dull"); listBox1.Items.Add("Vivacious"); listBox1.Items.Add("Plain"); listBox1.Items.Add("Outstanding"); listBox1.SelectedIndex = 3; this.Controls.Add(listBox1); } //Обробник події, що спрацьовує при натисканні кнопки
void button1_Click(object sender, System.EventArgs e) { // Виводимо повідомлення з зазначенням обраного в списку пункту MessageBox.Show(this, "You have selected " + listBox1.SelectedItem, "Notification", MessageBoxButtons.OK); } static void Main() { // Запускаємо новий екземпляр програми Windows Forms за допомогою вищеописаного класу Application.Run(new MyForm()); } }
Приклад програми 7
Отже, настала пора випробувати свої сили. Щоб продемонструвати використання ряду нових корисних елементів управління, ми спробуємо написати одну справді велику програму. Обсяг коду може здатися вам лякаюче великим, але ця програма може виявитися корисною в подальшому, коли вам потрібно буде згадати, як використовувати той чи інший елемент керування.
При цьому необов'язково вчитуватися в текст всієї програми досконально, але коли у вас виникнуть питання з використання, наприклад, елементу CheckBox, ви можете повернутися до неї і переглянути ту частину, яка стосується відповідного елемента.
Зверніть увагу, що для того щоб використовувати елементи керування PictureBox і DataGridView особливим чином, будуть потрібні простору імен System.Drawing, System.Data і System.Xml.
using System; using System.Windows.Forms; using System.Drawing; using System.Data; using System.Xml; class FormWithManyControls : Form { TreeView treeView1; Panel panel1; CheckBox checkBox1, checkBox2; RadioButton radiobutton1, radioButton2; ListBox listBox1; // Метод-конструктор нашого класу public FormWithManyControls() { // Вказуємо розміри і заголовок вікна this.Text = "A form dealing with many types of controls"; this.Width = 700; this.Height = 500; // Добавляємо елемент TreeView в якості своєрідного меню treeView1 = new TreeView(); treeView1.BackColor = Color.BurlyWood; treeView1.Dock = DockStyle.Left; treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(treeView1_AfterSelect); TreeNode tn = new TreeNode("Элементы"); tn.Expand(); tn.Nodes.Add(new TreeNode("[Очистить]")); tn.Nodes.Add(new TreeNode("Label")); tn.Nodes.Add(new TreeNode("Button")); tn.Nodes.Add(new TreeNode("CheckBox")); tn.Nodes.Add(new TreeNode("RadioButton")); tn.Nodes.Add(new TreeNode("ListBox")); tn.Nodes.Add(new TreeNode("TextBox")); tn.Nodes.Add(new TreeNode("TabControl")); tn.Nodes.Add(new TreeNode("DataGridView")); tn.Nodes.Add(new TreeNode("MainMenu")); tn.Nodes.Add(new TreeNode("ToolBar")); tn.Nodes.Add(new TreeNode("PictureBox")); tn.Nodes.Add(new TreeNode("RichTextBox")); treeView1.Nodes.Add(tn); this.Controls.Add(treeView1); // Добавляємо панель для розміщення інших елементів управління panel1 = new Panel(); panel1.Dock = DockStyle.Right; panel1.BorderStyle = BorderStyle.Fixed3D; panel1.Width = this.Width - treeView1.Width; this.Controls.Add(panel1); } // Обробник подій, що спрацьовує при виборі одного з вузлів дерева TreeView private void treeView1_AfterSelect (object sender, System.Windows.Forms.TreeViewEventArgs e) { //Виконання відповідної дії при виборі будь-якого з вузлів if (e.Node.Text == "[Wipe clean]") { // Видаляємо з панелі всі елементи управління panel1.Controls.Clear(); } else if (e.Node.Text == "Button") { // Добавляємо на панель кнопку Button button1 = new Button(); button1.Text = "I'm a button"; button1.Location = new Point(150, 80); button1.Click += new EventHandler(button1_Click); panel1.Controls.Add(button1); } else if (e.Node.Text == "Label") { // Добавляємо на панель мітку Label label1 = new Label(); label1.Text = "This is a label. Labels are simply used " + "to write text at a point on the screen"; label1.Location = new Point(150, 10); label1.Width = 400; label1.Click += new EventHandler(label1_Click); panel1.Controls.Add(label1); } else if (e.Node.Text == "CheckBox") { // Добавляємо на панель кілька прапорців checkBox1 = new CheckBox(); checkBox1.Text = "I am sharp"; checkBox1.Location = new Point(10, 50); checkBox1.CheckedChanged += new EventHandler(CheckBox_CheckedChanged); panel1.Controls.Add(checkBox1); checkBox2 = new CheckBox(); checkBox2.Text = "I am modest"; checkBox2.Location = new Point(10, 70); checkBox2.CheckedChanged += new EventHandler(CheckBox_CheckedChanged); panel1.Controls.Add(checkBox2); } else if (e.Node.Text == "RadioButton") { // Добавляємо на панель кілька перемикачів radiobutton1 = new RadioButton(); radiobutton1.Text = "I am sharp"; radiobutton1.Location = new Point(370, 210); radiobutton1.CheckedChanged += new EventHandler(RadioButton_CheckedChanged); panel1.Controls.Add(radiobutton1); radioButton2 = new RadioButton(); radioButton2.Text = "I am dim-witted"; radioButton2.Location = new Point(370, 230); radiobutton1.CheckedChanged += new EventHandler(RadioButton_CheckedChanged); panel1.Controls.Add(radioButton2); } else if (e.Node.Text == "ListBox") { // Добавляємо на панель список listBox1 = new ListBox(); listBox1.Items.Add("Green"); listBox1.Items.Add("Beige"); listBox1.Items.Add("White"); listBox1.Location = new Point(200, 180); listBox1.SelectedIndexChanged += new EventHandler(listBox1_SelectedIndexChanged); panel1.Controls.Add(listBox1); } else if (e.Node.Text == "TextBox") { // Добавляємо на панель текстовое поле TextBox TextBox1 = new TextBox(); TextBox1.Text = "You can type here"; TextBox1.Location = new Point(10, 110); panel1.Controls.Add(TextBox1); } else if (e.Node.Text == "DataGridView") { // Добавляємо на панель таблицю, заповнену даними з файлу xml DataSet dataSet1 = new DataSet("A sample DataSet"); dataSet1.ReadXml("../../data/grades.xml"); DataGridView dataGridView1 = new DataGridView(); dataGridView1.Width = (panel1.Width / 2) - 10; dataGridView1.Height = 150; dataGridView1.Location = new Point(2, panel1.Height - dataGridView1.Height - 5); dataGridView1.DataSource = dataSet1; dataGridView1.DataMember = "subject"; panel1.Controls.Add(dataGridView1); } else if (e.Node.Text == "TabControl") { // Добавляємо на панель элемент управління вкладками // і наповнюємо кожну вкладку вмістом TabControl tabControl1 = new TabControl(); tabControl1.Location = new Point(10, 150); tabControl1.Size = new Size(165, 146); TabPage tabPage1 = new TabPage("Robynne"); PictureBox pictureBox1 = new PictureBox(); pictureBox1.Image = new Bitmap("../../images/robynne.jpg"); pictureBox1.Size = new Size(160, 120); tabPage1.Controls.Add(pictureBox1); tabControl1.TabPages.Add(tabPage1); TabPage tabPage2 = new TabPage("Her Dog"); PictureBox pictureBox2 = new PictureBox(); pictureBox2.Image = new Bitmap("../../images/chocolate.jpg"); pictureBox2.Size = new Size(160, 120); tabPage2.Controls.Add(pictureBox2); tabControl1.TabPages.Add(tabPage2); TabPage tabPage3 = new TabPage("Info"); tabPage3.BackColor = Color.White; Label label1 = new Label(); label1.Text = "Robynne lives in Cape Town, South Africa.\n\n" + "She has a dog named Chocolate, from the planet Woof," + " rapidly growing into her oversized ears."; label1.Dock = DockStyle.Fill; tabPage3.Controls.Add(label1); tabControl1.TabPages.Add(tabPage3); panel1.Controls.Add(tabControl1); } else if (e.Node.Text == "PictureBox") { // Добавляємо на панель зображення PictureBox pictureBox1 = new PictureBox(); pictureBox1.Image = new Bitmap("../../images/ocean.jpg"); pictureBox1.BorderStyle = BorderStyle.Fixed3D; pictureBox1.Location = new Point(250, 25); pictureBox1.Size = new Size(300, 130); panel1.Controls.Add(pictureBox1); } else if (e.Node.Text == "RichTextBox") { // Добавляємо поле для вводу тексту з форматуванням // Завантажуємо в нього дані з файлу XML RichTextBox richTextBox1 = new RichTextBox(); richTextBox1.LoadFile("../../data/grades.xml", RichTextBoxStreamType.PlainText); richTextBox1.WordWrap = false; richTextBox1.BorderStyle = BorderStyle.Fixed3D; richTextBox1.BackColor = Color.Beige; richTextBox1.Size = new Size((panel1.Width / 2) - 10, 150); richTextBox1.Location = new Point((panel1.Width / 2) + 10, panel1.Height - richTextBox1.Height - 5); panel1.Controls.Add(richTextBox1); } else if (e.Node.Text == "MainMenu") { // Добавляємо класичне «меню» (появляється в верхній частині вікна) MainMenu mainMenu1 = new MainMenu(); MenuItem menuItem1 = new MenuItem("File"); menuItem1.MenuItems.Add("Exit", new EventHandler(mainMenu1_Exit_Select)); mainMenu1.MenuItems.Add(menuItem1); MenuItem menuItem2 = new MenuItem("Background"); menuItem2.MenuItems.Add("Choose", new EventHandler(mainMenu1_ColorOwn_Select)); menuItem2.MenuItems.Add("White", new EventHandler(mainMenu1_ColorWhite_Select)); mainMenu1.MenuItems.Add(menuItem2); this.Menu = mainMenu1; MessageBox.Show("A main menu has been added at the top " + "left of the window. Try it out after clicking OK."); } else if (e.Node.Text == "ToolBar") { // Добавляємо на панель елемент "панель управління" з кнопками швидкого виклику ToolBar toolBar1 = new ToolBar(); ImageList imageList1 = new ImageList(); imageList1.Images.Add(new Bitmap("../../images/open.gif")); imageList1.Images.Add(new Bitmap("../../images/close.gif")); imageList1.Images.Add(new Bitmap("../../images/undo.gif")); toolBar1.ImageList = imageList1; ToolBarButton toolBarbutton1 = new ToolBarButton("Open"); toolBarbutton1.ImageIndex = 0; toolBar1.Buttons.Add(toolBarbutton1); ToolBarButton toolBarbutton2 = new ToolBarButton("Close"); toolBarbutton2.ImageIndex = 1; toolBar1.Buttons.Add(toolBarbutton2); ToolBarButton toolBarButton3 = new ToolBarButton("Huh"); toolBarButton3.ImageIndex = 3; toolBar1.Buttons.Add(toolBarButton3); toolBar1.ButtonClick += new ToolBarButtonClickEventHandler(toolBar1_Click); panel1.Controls.Add(toolBar1); } } /* Обробники подій для доданих вище елементів управління */ // Обробник події, що спрацьовує при натисканні мишею на мітці void label1_Click(object sender, System.EventArgs e) { MessageBox.Show ("Yes, labels can be clicked, although it's not normal to do so."); } // Обробник події, що спрацьовує при натисканні кнопки void button1_Click(object sender, System.EventArgs e) { MessageBox.Show("Yup, you were supposed to click me"); } // Обробник події, що спрацьовує при натисканні встановленні чи знятті прапорця
void CheckBox_CheckedChanged(object sender, System.EventArgs e) { if (checkBox1.Checked && checkBox2.Checked) { MessageBox.Show("Good for you"); } else if (checkBox1.Checked) { MessageBox.Show("It's not good to be sharp without being modest"); } else if (checkBox2.Checked) { MessageBox.Show("Modesty is good. Pity you're not sharp too."); } else { MessageBox.Show("Oh dear, neither sharp nor modest eh?"); } } // Обробник події, що спрацьовує при натисканні перемикача void RadioButton_CheckedChanged(object sender, System.EventArgs e) { if (radiobutton1.Checked) { MessageBox.Show("Glad to hear it"); } else if (radioButton2.Checked) { MessageBox.Show("What a shame"); } } // Обробник події, що спрацьовує при виборі одного з пунктів списку
void listBox1_SelectedIndexChanged(object sender, System.EventArgs e) { if (listBox1.SelectedItem.ToString() == "Green") { treeView1.BackColor = Color.LightSeaGreen; } else if (listBox1.SelectedItem.ToString() == "Beige") { treeView1.BackColor = Color.Beige; } else if (listBox1.SelectedItem.ToString() == "White") { treeView1.BackColor = Color.White; } }
// Обробник події, що спрацьовує при виборі в меню пункту "White"
void mainMenu1_ColorWhite_Select(object sender, System.EventArgs e) { treeView1.BackColor = Color.White; }
// Обробник події, що спрацьовує при виборі в меню кольору
void mainMenu1_ColorOwn_Select(object sender, System.EventArgs e) { ColorDialog colorDialog1 = new ColorDialog(); colorDialog1.Color = treeView1.BackColor; colorDialog1.ShowDialog(); treeView1.BackColor = colorDialog1.Color; }
// Обробник події, що спрацьовує при виборі в меню пункту "exit"
void mainMenu1_Exit_Select(object sender, System.EventArgs e) { if ( MessageBox.Show("Are you sure you want to exit?", "Exit confirmation", MessageBoxButtons.YesNo) == DialogResult.Yes ) { this.Dispose(); } } // Оброблювач події, що спрацьовує при натисканні кнопки на панелі інструментів void toolBar1_Click (object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e) { if (e.Button.Text == "Open") { MessageBox.Show("This could have opened a file, for example"); } else if (e.Button.Text == "Close") { MessageBox.Show("This could have closed a file, for example"); } else if (e.Button.Text == "Huh") { MessageBox.Show("Huh?"); } } static void Main() { // Запускаємо новий екземпляр програми Windows Forms за допомога вище описаного класу Application.Run(new FormWithManyControls()); } }
Вступ
Класи, об'єднані в простір імен Drawing, дозволяють працювати з різними зображеннями. Існує два основних типи комп'ютерних зображень:
Точкові чи растрові;
Векторні.
Растрові зображення є набором точок. Прикладом їх можуть служити фотографії та значки.
Векторна графіка - це зображення, складені з певних геометричних фігур: ліній, кіл, прямокутників і т.д. Наприклад, план будинку зручно представляти у вигляді векторного зображення.
Для початку продемонструємо роботу з растровою графікою. На комп'ютері часто доводиться виконувати обробку зображень, наприклад, працювати з фотографіями. У бібліотеці класів. NET Framework є для цього чимало корисних засобів.
Приклад програми 8Ця програма знаходить зображення (в даному випадку файл JPEG) на диску і відображає його на формі. Для цього нам знадобиться який-небудь елемент управління, що дозволяє відображати зображення. PictureBox чудово підходить для цієї мети.
using System; using System.Windows.Forms; using System.Drawing; class PictureDisplayer : Form { Bitmap image1; PictureBox pictureBox1; // Метод-конструктор нашого класу public PictureDisplayer() { // Вказуємо розміри і заголовок вікна this.Text = "Picture Displayer"; this.Size = new Size(302, 240); // Готуємо поле для розміщення зображення pictureBox1 = new PictureBox(); pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; pictureBox1.BorderStyle = BorderStyle.Fixed3D; pictureBox1.ClientSize = new Size(300, 196); // Добавляємо зображення до елемента PictureBox image1 = new Bitmap(@"../../images/lama.jpg"); pictureBox1.Image = (Image)image1; // Добавляємо PictureBox (з зображенням) на форму this.Controls.Add(pictureBox1); } static void Main() { // Запускаємо новий екземпляр програми Windows Forms за допомогою вищеописаного класу Application.Run(new PictureDisplayer()); } }
Приклад програми 9
Наступна програма завантажує фотографію з диска і після натискання кнопки «flip» (Перевернути) дозволяє отримати її дзеркальне відображення по горизонталі.
using System; using System.Windows.Forms; using System.Drawing; class PictureFlipper : Form { Button button1; Bitmap image1; PictureBox pictureBox1; // Метод-конструктор нашого класу public PictureFlipper() { // Вказуємо розміри і заголовок вікна this.Text = "Picture Flipper"; this.Size = new Size(302, 240); // Добавляємо на форму кнопку button1 = new Button(); button1.Text = "Flip"; button1.Location = new Point(100, 150); button1.Click += new System.EventHandler(button1_Click); this.Controls.Add(button1); // Добавляємо елемент PictureBox на форму pictureBox1 = new PictureBox(); pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; pictureBox1.BorderStyle = BorderStyle.Fixed3D; pictureBox1.ClientSize = new Size(300, 196); // Добавляємо зображенння в елемент PictureBox image1 = new Bitmap(@"../../images/elephants.jpg"); pictureBox1.Image = (Image)image1; // Добавляємо елемент PictureBox (з зображенням) на форму this.Controls.Add(pictureBox1); } static void Main() { // Запускаємо новий екземпляр програми Windows Forms за допомогою вищеописаного класу Application.Run(new PictureFlipper()); } // Обробник події, що спрацьовує при натисканні кнопки void button1_Click(object sender, EventArgs e) { // Flip the image along the X axis (horizontally) image1.RotateFlip(RotateFlipType.RotateNoneFlipX); // Повторно вставляємо зображення в елемент PictureBox pictureBox1.Image = (Image)image1; // Оновлюємо заголовок вікна this.Text = "Picture was flipped"; } }
Тепер перейдемо до прикладів роботи з векторною графікою - зображень, складеним з окремих геометричних фігур. У всіх цих прикладах буде створюватися кнопка і обробник подій, що перехоплює її натискання. Робота з графікою буде починатися тільки після натискання кнопки. Необхідно засвоїти кілька важливих принципів. Вони цілком логічні, але не знаючи їх, можна випробувати деякі труднощі.
У звичайному світі щоб намалювати лінію, коло, прямокутник або іншу фігуру, необхідно спочатку вибрати олівець потрібного кольору і товщини. Аналогічно, для відтворення на комп'ютері найпростіших фігур потрібно попередньо створити об'єкт Pen (Перо). Наприклад, за допомогою даного фрагмента коду створюється об'єкт Pen, який малює зелену лінію товщиною 3 пікселі:
Pen myGreenPen = new Pen (Color.Green, 3);
Для малювання фігур із заливкою потрібно щось на зразок кисті з фарбами.
Для створення фігур із заливкою на комп'ютері потрібно попередньо створити об'єкт Brush (Кисть) і вибрати колір заливки. Є різні типи кисті. У наступному фрагменті коду створюється об'єкт SolidBrush (Суцільна кисть) блакитного кольору:
SolidBrush myBlueBrush = new SolidBrush (Color.Blue);
Приклад програми 10
У цій програмі за допомогою методу DrawSomeShapes малюється лінія, прямокутник і еліпс («сплюснуте» коло).
using System; using System.Windows.Forms; using System.Drawing; class SimpleShapeMaker : Form { // Метод-конструктор нашого класу public SimpleShapeMaker() { // Міняємо колір фону форми на білий this.BackColor = Color.White; // Добавляємо на форму кнопку і прив'язуємо її до обробника подій Button button1 = new Button(); button1.Text = "click me"; button1.Location = new Point(110, 10); button1.BackColor = Color.SteelBlue; button1.Click += new System.EventHandler(button1_Click); this.Controls.Add(button1); } // Обробник події, що спрацьовує при натисканні кнопки void button1_Click(object o, System.EventArgs e) { // Виконання описаного нами методу DrawSomeShapes(); } // Метод для відтворення на поверхні форми кількох фігур void DrawSomeShapes() { // Підготовка області малювання на формі Graphics g = this.CreateGraphics(); // Готуємо перо, що малює червону лінію товщиною 3 пікселі Pen redPen = new Pen(Color.Red, 3); // За допомогою пера малюємо пряму лінію, прямокутник і овал g.DrawLine(redPen, 140, 170, 140, 230); g.DrawRectangle(redPen, 50, 60, 50, 60); g.DrawEllipse(redPen, 150, 100, 100, 60); // Очистка g.Dispose(); } static void Main() { // Запускаємо новий екземпляр програми Windows Forms за допомогою вищеописаного класу Application.Run( new SimpleShapeMaker() ); } }
Приклад програми 11
Спробуємо тепер пограти з мишкою. Працювати з графікою зазвичай зручніше за допомогою миші, а не клавіатури. У цьому прикладі ми будемо працювати як з растровими, так і з векторними зображеннями, використовуючи деякі події миші. Постараємося освоїти деякі нові дії з графікою, а саме з точковими малюнками. Ми не станемо писати про це цілий нарис, але невеликий вступ просто необхідно, щоб зрозуміти принципи роботи наведеного нижче коду.
Комп'ютерні програми формують зображення на екрані монітора, керуючи кольором і яскравістю маленьких крапок, званих пікселями.
Колір пікселя визначається трьома колірними компонентами: червоної (red), зеленої (green) і синій (blue) (в мовах програмування часто використовується скорочення RGB). Колір і яскравість пікселя управляється шляхом зміни інтенсивності компонент RGB, звичайно в межах від 0 до 255. Наприклад:
якщо red = 255, green = 0, blue = 0, колір пікселя буде яскраво-червоним;
якщо red = 255, green = 255, blue = 0, колір пікселя буде жовтим.
Комп'ютер може відслідковувати положення курсору миші, яке визначається координатами X і Y (горизонтальна і вертикальна координати). Так, верхній лівий кут екрана має координати X = 0 і Y = 0.
using System; using System.Windows.Forms; using System.Drawing; class FunWithTheMouse : Form { // Оголошуємо об'єкти, до яких будемо звертатися з різних методів PictureBox pictureBox1; Label label1; Point spotClicked; // Метод-конструктор нашого класу public FunWithTheMouse() { // Задаємо розміри вікна this.Size = new Size(640, 480); // Загружаем фотографию в элемент PictureBox і додаємо його на форму pictureBox1 = new PictureBox(); pictureBox1.Image = (Image)new Bitmap(@"../../images/foal.jpg"); pictureBox1.SizeMode = PictureBoxSizeMode.Normal; pictureBox1.Dock = DockStyle.Fill; this.Controls.Add(pictureBox1); // Добавляємо мітку з інструкціями в нижню частину екрана label1 = new Label(); label1.BackColor = Color.Wheat; label1.Dock = DockStyle.Bottom; label1.Text = "Drag rectangle with left mouse button (draw) or another " + "mouse button (lighten). To scribble, hold SHIFT and move mouse."; label1.TextAlign = ContentAlignment.MiddleCenter; this.Controls.Add(label1); // Прив'язуємо PictureBox до обробникам подій миші this.pictureBox1.MouseDown += new MouseEventHandler(MouseButtonIsDown); this.pictureBox1.MouseUp += new MouseEventHandler(MouseButtonIsUp); this.pictureBox1.MouseMove += new MouseEventHandler(TheMouseMoved); } // Обробник подій, що спрацьовує при ПЕРЕМІЩЕННІ миші public void TheMouseMoved(object sender, MouseEventArgs e) { // Якщо на клавіатурі натиснута клавіша SHIFT if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) { // Підготовка області малювання на зображенні System.Drawing.Graphics g = this.pictureBox1.CreateGraphics(); // Використовуємо жовте перо System.Drawing.Pen yellowPen = new System.Drawing.Pen(Color.Yellow, 3); // Малюємо коло (еліпс, вписаний в квадрат) // Верхній лівий кут квадрата має координати X і Y поточного положення миші g.DrawEllipse(yellowPen, e.X, e.Y, 40, 40); // Очистка g.Dispose(); } } // Обробник подій, що спрацьовує при натисканні кнопки миші public void MouseButtonIsDown(object sender, MouseEventArgs e) { // Запам'ятовуємо точку, в якій відбулося натискання кнопки миші. коли // Кнопка буде відпущена, нам знадобляться її координати spotClicked.X = e.X; // горизонтальна координата spotClicked.Y = e.Y; // вертикальна координата } // Оброблювач подій, що спрацьовує при Відрусканні кнопки миші public void MouseButtonIsUp(object sender, MouseEventArgs e) { /* Пользователь отпустил кнопку мыши! */ // Створюємо прямокутник (поки його ще не видно), що обмежує // Область зображення, з якою користувач буде працювати Rectangle r = new Rectangle(); // Лівий верхній кут відповідає точці, в якій була натиснута кнопка миші // Ми зберегли її координати за допомогою описаного вище методу r.X = spotClicked.X; r.Y = spotClicked.Y; // Ширина и высота прямокутника обчислюється // шляхом віднімання початкових координат миші (в точці натискання) // від поточних координат (в точці відпускання кнопки) r.Width = e.X - spotClicked.X; r.Height = e.Y - spotClicked.Y; if (e.Button == MouseButtons.Left) { /* ЯКЩО була натиснута і відпущена ліва кнопка миші малюємо видимий контур прямокутника * / // Підготовка області малювання на зображенні Graphics g = this.pictureBox1.CreateGraphics(); //Малюємо червоний контур прямокутника Pen redPen = new Pen(Color.Red, 2); g.DrawRectangle(redPen, r); } else { // ЯКЩО Була натіснута Інша кнопка, викликаємо складніший // Метод, який підсвічується область зображення ChangeLightness(r); } } // Метод, який збільшує яскравість вибраної ділянки зображення // Шляхом збільшення яскравості кожного пікселя цієї ділянки
public void ChangeLightness(Rectangle rect) { int newRed, newGreen, newBlue; Color pixel; // Копіюємо зображення, завантажене в PictureBox System.Drawing.Bitmap picture = new Bitmap(this.pictureBox1.Image); // Оскільки операція збільшення яскравості може зайняти багато часу, // Обов'язково попередити про це користувача, якщо обрано велику ділянку if ( (rect.Width>150) || (rect.Height>150 ) ) { DialogResult result = MessageBox.Show ( "The area you selected is large and may take a long time to lighten", "Warning", MessageBoxButtons.OKCancel ); // При натисканні кнопки Cancel (Скасувати) виходимо з методу // і повертаємося до місця його виклику if ( result == DialogResult.Cancel ) return; } /* Перебираємо послідовно всі пікселі даної ділянки і подвоюємо значення яскравості компонент RGB пікселів */ // Перебір по горизонталі зліва направо ... for (int x = rect.X; x < rect.X + rect.Width; x++) { // і по вертикалі зверху вниз ... for (int y = rect.Y; y < (rect.Y + rect.Height); y++) { // Зчитуємо поточний піксель pixel = picture.GetPixel(x, y); // Збільшуємо яскравість колірних компонент пікселя newRed = (int)Math.Round(pixel.R * 2.0, 0); if (newRed > 255) newRed = 255; newGreen = (int)Math.Round(pixel.G * 2.0, 0); if (newGreen > 255) newGreen = 255; newBlue = (int)Math.Round(pixel.B * 2.0, 0); if (newBlue > 255) newBlue = 255; //Надаємо пікселю нові колірні значення picture.SetPixel ( x, y, Color.FromArgb((byte)newRed,(byte)newGreen, (byte)newBlue) ); } } // Розміщуємо змінену копію зображення в PictureBox // Щоб зміни відобразилися на екрані
this.pictureBox1.Image = picture; } static void Main() { // Створюємо екземпляр класу форми Application.Run(new FunWithTheMouse()); } }
Вступ
На практиці більшість програм слід працювати з базами даних. Будь-який програміст з великої компанії, підтвердить вам, наскільки велика роль баз даних у світі обчислювальних технологій. Програміст, що вміє оперувати з базами даних, здатний створювати найрізноманітніші і дійсно корисні додатки.
Можливо, у вас на комп'ютері вже встановлена система управління базами даних, наприклад Microsoft Access. Як альтернативу можна встановити Microsoft SQL Server Express Edition. З його допомогою можна навчитися працювати з базами даних SQL Server, використовуваними в багатьох найбільших компаніях по всьому світу. SQL Server Express включений в пакет установки Visual C # Express, так що можливо ви вже встановили його.
Для роботи з базами даних в бібліотеці. NET Framework передбачені класи простору імен System.Data. База даних в корені відрізняється від таких об'єктів, як зображення або документи текстових редакторів, які часто називають неструктурованими. Інформація в базі даних більш структурована. Зазвичай вона містить рядки, які містять дані одного типу і що об'єднуються в блоки, звані таблицями. Таблиця складається з одного або декількох стовпців, що містять певну інформацію для кожного рядка.
Рядки іноді називають записами, а стовпці - полями.
Нижче представлена таблиця бази даних, що містить інформацію про планети. Вона має такі стовпці: PlanetName (назва планети), DistanceFromSun (відстань до Сонця) і Inhabitants (мешканці).
З наведеної таблиці видно, наприклад, що Венера знаходиться на відстані 108 200 тисяч кілометрів від Сонця, а істоти, що її населяють, іменуються венеріанці.
Ось ще одна таблиця, в якій містяться відомості про щорічну чисельності мешканців різних планет.
Це абсолютно секретна інформація, ніде раніше не оприлюднена. Вона була отримана з інопланетного зорельота, який зазнав аварії в самій глибині пустелі Гобі. Це велика честь - мати можливість ознайомитися з нею. Очевидно, представники інопланетної цивілізації теж використовують бази даних SQL Server Express, що і дало нам можливість привести тут ці відомості як приклад.
Ви можете бачити, що в таблиці є два рядки, що стосуються Венери. Зверніть увагу, що в 2000 році на Венері мешкало 25 венеріанці, а в 2001 році їх чисельність скоротилася до трьох. Ймовірно, це сталося в результаті вивержень вулканів.
Мова SQL
Існує безліч різноманітних систем управління базами даних: Microsoft Access, Oracle, DB2, Microsoft SQL Server, Informix, mySQL, і це далеко не повний список. Отже, як же відбувається звернення до бази даних з програми на мові C #? Як «пояснити» базі даних, що нам потрібно?
Найпростішим рішенням є включення в код C # фрагмента на «мові бази даних», за допомогою якого і здійснюється запит до бази даних на отримання потрібних стовпців і рядків.
(По правді кажучи, існує ще проміжний рівень, званий ADO.NET, але ми не станемо зараз загострювати на ньому увагу)
Багато років тому фахівці по базах даних зібралися і домовилися про використання «єдиної мови баз даних», який розуміли б більшість існуючих баз даних. Ця мова називається SQL (від англ. Structured Query Language - мова структурованих запитів). Не слід плутати мову SQL c системою управління базами даних SQL Server, розробленої корпорацією Microsoft. Мова SQL підтримується СУБД від самих різних виробників.
Перш ніж починати розмову про роботу з базами даних з використанням C #, давайте познайомимося з основами мови SQL. Нижче наведені приклади операторів на мові SQL і описується результат їх виконання.
Три основних команди SQL це: SELECT для перегляду деяких даних, INSERT для додавання нових даних і UPDATE для зміни існуючих даних. Наведемо приклади кожної з них.
Як правило, оператор SELECT записується наступним чином:
SELECT <імена видобутих стовпців>
FROM <відповідні таблиці бази даних>
WHERE <умова, яка повинна виконуватися>
SELECT *
FROM PLANET
Він повертає всі рядки і всі стовпці з бази даних PLANET (зірочка * означає вибір всіх стовпців таблиці).
Не слід плутати бази даних з електронними таблицями. Хоча спосіб представлення даних в електронних таблицях зовні схожий на той, що використовувався в наведених вище прикладах, обробка даних відбувається в них зовсім інакше.
SELECT PlanetName, Inhabitants FROM PLANET
Цей запит повертає стовпці «PlanetName» і «Inhabitants» з усіма рядками з таблиці PLANET.
SELECT PlanetName, Inhabitants
FROM PLANET
WHERE PlanetName='Venus'
Такий запит повертає стовпці «PlanetName» і «Inhabitants» з таблиці PLANET. В результат його виконання будуть включені тільки ті рядки, які містять значення «Venus» у стовпці PlanetName.
PlanetName
Inhabitants
Venus
Venusians
SELECT PlanetName, Population
FROM POPULATION
WHERE Population<100000
Даний запит повертає рядки стовпців PlanetName і Population з таблиці POPULATION, для яких значення стовпця Population менше 100000.
Як правило, оператор INSERT записується наступним чином:
INSERT INTO <таблиця бази даних, до якої додаються рядки>
(<стовпці, в які будуть додаватися значення>)
INSERT INTO PLANET (PlanetName, DistanceFromSun, Inhabitants) VALUES ('Fluff', 23500000, 'Fluffies')
Оператор INSERT додає в таблицю PLANET новий рядок. Він не повертає будь-якого результату в програму, але заради наочності ми покажемо, який вид прийме таблиця після його виконання.
Як правило, оператор UPDATE записується наступним чином:
UPDATE <таблиця бази даних, в яку вносяться зміни>
SET <стовпці, до яких необхідно внести зміни> = <нові значення>
UPDATE PLANET SET PlanetName='Stuff', Inhabitants='Stuffies' WHERE PlanetName='Fluff'
Оператор змінює деякі значення в рядку, в якій стовпець PlanetName має значення «Fluff» і теж не повертає якийсь результат в програму. Далі показано, який вигляд прийме таблиця після його виконання.
Зв'язки та об'єднання
Якщо ви звернете увагу, то помітите, що між таблицями PLANET і POPULATION існує зв'язок. В обох таблицях є стовпець з ім'ям «PlanetName». Ми говоримо, що ці таблиці зв'язані по стовпцю «PlanetName». Завдяки цьому можна зібрати всю інформацію про певну планеті.
Наприклад, можна вибрати з обох таблиць всі рядки, що стосуються Венери ...
і об'єднати їх в одну велику таблицю ...
SELECT * FROM PLANET INNER JOIN POPULATION ON PLANET.PlanetName=POPULATION.planetName WHERE PlanetName='Venus'
Використання СУБД
Існують причини, за якими в деяких ситуаціях для роботи з певною СУБД потрібні особливі програмні рішення. Так, в середовищі. NET існують різні способи роботи з даними. Наприклад, якщо використовується база даних Microsoft SQL Server, можна використовувати спеціальні об'єкти, що дозволяють значно прискорити виконання SQL-запитів. Однак для звернення до бази даних Microsoft Access ці об'єкти використовувати не можна. \
Тому код програм буде трохи відрізнятися в залежності від того, чи використовуєте ви SQL Server. Тому ми вчинили так.
Три приклади програм, що працюють з базами даних, у цьому розділі (12a, 13a і 14a) припускають використання SQL Server Express (або іншої версії SQL Server).
В іншому випадку ви можете знайти на диску приклади відповідних програм, розрахованих на роботу з Microsoft Access (12b, 13b і 14b). Для їхнього запуску взагалі не потрібна установка будь-якої СУБД.
Тим не менш, ми б рекомендували вам рано чи пізно встановити SQL Server Express, що забезпечує більш широкі можливості програмування. Крім того, вміння працювати з SQL Server набагато вище цінується у діловій сфері, і чим швидше ви освоїте SQL Server, тим краще. Завантажити його можна безкоштовно за адресою: http://www.microsoft.com/express/ru/sql/download/default.aspx.
Зверненя до бази даних з програми на мові C#
У наступних зразках програм на C# будуть застосовані класи SqlConnection і SqlCommand, що забезпечують взаємодію з базою даних SQL Server Express під назвою «Planets». Ці класи призначені спеціально для роботи з базами даних Microsoft SQL Server будь-якої версії. Далі ми будемо працювати з даними двома різними способами:
З використанням класу SqlDataReader, який забезпечує різноманітні можливості програмного управління базою даних, дозволяючи порядково перебирати дані і виконувати різні дії над обраними значеннями.
З використанням класів SqlDataAdapter і DataSet (набір даних) для організації автоматичного відображення рядків даних за допомогою таких елементів керування, як DataGrid. При такому підході для добування інформації з бази даних буде потрібно пристойний обсяг коду, але її висновок можна реалізувати без особливих зусиль, бо такі «розумні» елементи управління, як DataGridView легко прив'язуються до набору даних.
Приклад програми 12
Наступна програма підключається до бази даних SQL Server Express і посилає їй SQL-запит. Після отримання результату запиту здійснюється перебір рядків і висновок кожного значення зі стовпця PlanetName в елемент керування Label з нового рядка.
Код програми 12a (для роботи з SQL Express; для роботи з Microsoft Access потрібна версія 12b, наявна на диску)
using System.Windows.Forms; using System.Data; using System.Data.SqlClient; // Пространство имен для работы с базами данных SQL Server class SimpleDataAccess : Form { public SimpleDataAccess() { // Вказуємо заголовок вікна this.Text = "A simple databasing program"; // Указываем физический путь к базе данных PLANETS string dbLocation = System.IO.Path.GetFullPath("../../../database/SqlServer/planets.mdf"); // Добавляємо метку и растягиваем ее на всю поверхность формы Label label1 = new Label(); label1.Dock = DockStyle.Fill; this.Controls.Add(label1); // Подключаемся к базе данных SQL Server SqlConnection connection1 = new SqlConnection ( @"data source=.\SQLEXPRESS;" + "User Instance=true;Integrated Security=SSPI;AttachDBFilename=" + @dbLocation ); connection1.Open(); // Формируем запрос к базе данных - запрашиваем информацию о планетах string sql = "SELECT * FROM PLANET"; SqlCommand command1 = new SqlCommand(sql, connection1); SqlDataReader dataReader1 = command1.ExecuteReader(); // Організовуємо циклічний перебір отриманих записів і Виводимо назву кожної планети на мітку while (dataReader1.Read()) { label1.Text = label1.Text + dataReader1["PlanetName"] + "\n"; } // Очистка dataReader1.Close(); connection1.Close(); } static void Main() { // Запускаємо новий екземпляр програми Windows Forms за допомогою вищеописаного класу Application.Run(new SimpleDataAccess()); } }
Приклад програми 13
У наступній програмі потрібно вивести на екран кілька стовпців даних.
Елемент управління Label занадто незручний для цього, тому скористаємося елементом DataGridView.
Програма виконує той же запит, що і в попередньому прикладі, але поміщає результат в об'єкт DataSet, який підключається до елементу управління DataGridView і в результаті той автоматично відображає всі дані.
Підключення будь-якого прихованого джерела даних до візуального елементу управління називається прив'язкою даних.
Код програми 13a (для роботи з SQL Express; для роботи з Microsoft Access потрібна версія 13b, наявна на диску)
using System.Windows.Forms; using System.Data; using System.Data.SqlClient; // Простір імен для роботи з базами даних SQL Server class DataInGrid : Form { public DataInGrid() { // Вказуємо заголовок вікна this.Text = "One-Way Database Grid Binding"; // Вказуємо фізичний шлях до бази даних PLANETS string dbLocation = System.IO.Path.GetFullPath("../../../database/SqlServer/planets.mdf"); // Добавляємо елемент DataGridView на форму DataGridView DataGridView1 = new DataGridView(); DataGridView1.Width = this.Width; DataGridView1.Height = 250; DataGridView1.DataMember = "Table"; DataGridView1.Dock = DockStyle.Fill; this.Controls.Add(DataGridView1); // Подключаемся к базе данных SQL Server SqlConnection connection1 = new SqlConnection ( @"data source=.\SQLEXPRESS; + "User Instance=true;Integrated Security=SSPI;AttachDBFilename=" + @dbLocation ); connection1.Open(); // DataSet сохраняет данные в памяти с помощью таблиц данных DataTable DataSet dataSet1 = new DataSet(); // Объект DataAdapter является посредником при взаимодействии базы данных и объекта DataSet SqlDataAdapter sqlDataAdapter1 = new SqlDataAdapter(); // Указываем объекту DataAdapter, какие данные он должен получить и откуда sqlDataAdapter1.SelectCommand = new SqlCommand("SELECT * FROM PLANET", connection1); // Теперь заполняем находящийся в памяти объект DataSet данными sqlDataAdapter1.Fill(dataSet1); // Привязываем элемент DataGridView (визуальную таблицу) к хранящимся в памяти данным DataGridView1.DataSource = dataSet1; // Закрываем подключение к базе данных connection1.Close(); } static void Main() { // Запускаємо новий екземпляр програми Windows Forms за допомогою вищеописаного класу Application.Run(new DataInGrid()); } }
Приклад програми 14
Те, що ми навчилися відображати дані за допомогою елемента управління DataGridView, вже добре, але ви, напевно, звернули увагу, що при зміні даних вони не зберігаються в базі даних. Тому змінимо підхід і проведемо «двосторонню прив'язку даних».
Тут ми пустимося на маленьку хитрість (це називається «підвищити продуктивність своєї праці») і не станемо самі прописувати оператори UPDATE і INSERT. Простір імен System.Data містить «маленький, та молодецький» клас CommandBuilder, який вміє самостійно створювати команди SQL і автоматично їх виконувати.
Код програми 14a (для роботи з SQL Express; для роботи з Microsoft Access потрібна версія 14b, наявна на диску)
using System.Windows.Forms; using System.Data; using System.Data.SqlClient; // Пространство имен для работы с базами данных SQL Server class PlanetsForm : Form { // Объявляем объекты, к которым будем обращаться из разных методов DataGridView dg; SqlDataAdapter da; public PlanetsForm() // Метод-конструктор класса PlanetsForm { // Указываем заголовок окна this.Text = "Two-way Database Grid Binding"; // Указываем физический путь к базе данных PLANETS string dbLocation = System.IO.Path.GetFullPath("../../../database/SqlServer/planets.mdf"); // Подготавливаем подключение к базе данных SQL Server string connectionString = @"data source=.\SQLEXPRESS;" + "User Instance=true;Integrated Security=SSPI;AttachDBFilename=" + @dbLocation; /* Добавляємо на форму кнопку "Save" (Сохранить) */ Button btnSave = new Button(); btnSave.Text = "Save"; btnSave.Click += new System.EventHandler(BtnSave_Click); btnSave.Dock = DockStyle.Top; this.Controls.Add(btnSave); /* Добавляємо элемент DataGridView на форму */ dg = new DataGridView(); dg.Width = this.Width; dg.Height = 250; dg.Dock = DockStyle.Fill; this.Controls.Add(dg); /* Создаем экземпляры объектов для "умной" работы с данными и используем их вместе для привязки элемента DataGridView к требуемому источнику данных */ // Объект DataAdapter выступает в роли посредника при взаимодействии базы данных и хранящегося в памяти объекта DataTable da = new SqlDataAdapter("SELECT * FROM PLANET", connectionString); // Объект CommandBuilder автоматически выполняет команды UPDATE и INSERT SqlCommandBuilder cb = new SqlCommandBuilder(da); // Объект DataTable отслеживает и сохраняет в памяти изменения DataTable dt = new DataTable(); // Теперь заполняем объект DataTable данными da.Fill(dt); // Привязываем элемент управления DataGridView к объекту DataTable dg.DataSource = dt; } static void Main() { // Запускаємо новий екземпляр програми Windows Forms за допомогою вищеописаного класу Application.Run(new PlanetsForm()); } private void BtnSave_Click(object sender, System.EventArgs e) { // При нажатии кнопки "Save" в базе данных сохраняются любые изменения, // внесенные в источник данных, связанный с DataGridView, которым // в данном случае является объект DataTable da.Update((DataTable)dg.DataSource); MessageBox.Show ("Data has been saved", "For your information", MessageBoxButtons.OK); } }
Поекспериментуйте зі зміною існуючих і введенням нових значень. Натисніть кнопку «Save» і закрийте форму. Перезапустивши програму, можна переконатися, що змінені і додані значення були збережені в базі даних.
Що робити, якщо SQL Server Express не встановлено?
Якщо у вас не встановлено Microsoft SQL Server і ви користуєтеся інший СУБД, вам буде потрібно внести в код невеликі поправки.
По-перше, необхідно змінити рядок підключення з описом розташування бази даних, її типу і т.д.
Рядок підключення для бази даних SQL Server Express виглядає приблизно так:
string connectionString = "Integrated Security=SSPI;Persist Security Info=False; Initial Catalog=Northwind;Data Source=localhost";
або так, якщо підключення проводиться безпосередньо до файлу бази даних (як у прикладах з цієї книги):
string connectionString = @"data source=.\SQLEXPRESS;Integrated Security=SSPI; AttachDBFilename=c:\C#4#KIDS\examples\database\SqlServer\planets.mdf; User Instance=true”; (Зважаючи на брак місця рядок підключення розірвана тут на кілька рядків, але в дійсності вираз, укладену в лапки, має записуватися в один рядок.)
Рядок підключення для бази даних Microsoft Access буде виглядати приблизно так:
string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source c:\C#4#KIDS\examples\database\Access\planets.mdb;";
(Як пояснювалося раніше, вираз, що стоїть в лапках, має записуватися в один рядок.)
Для інших баз даних прийняті свої особливі формати рядка підключення. Приклади можна знайти в довідковій документації по Visual C # Express або в документації по використовуваної вами СУБД. Крім зміни рядка підключення потрібно замінити класи «SQL» на класи «OleDb».
Для початку необхідно включити простір імен System.Data.OleDb замість простору імен System.Data.SqlClient. Воно містить класи, призначені для роботи з різноманітними базами даних.
using System.Data.OleDb;
Потім проведіть заміну класів для роботи з даними, як зазначено нижче:
Якщо у вас встановлений і готовий до роботи Microsoft SQL Server Express, використовуйте приклади 12a, 13a і 14a. В іншому випадку, якщо у вас виникають проблеми з запуском цих програм, можна скористатися прикладами 12b, 13b і 14b, аналогічними по суті, але не вимагають установки СУБД.
Класи простору імен System.Xml дозволяють працювати з XML-даними різними способами.
Найбільш часто виконуються наступні завдання:
відкриття XML-документа;
читання фрагмента XML-даних для вилучення деяких значень;
збереження XML-файла на диск.
Короткий вступ до XML
Мова XML отримала в наші дні вкрай широке поширення, і, швидше за все, ви вже чули про нього. XML це прекрасний приклад мови, розрахованого як на людське, так і на комп'ютерне сприйняття. Як правило, дані, з якими працюють різні обчислювальні системи, здаються звичайним людям китайською грамотою, але XML-документи записуються у вигляді звичайного тексту.
Наприклад, можна скласти XML-документ для зберігання на диску деяких географічних даних:
<?xml version="1.0" encoding="utf-8" ?> South America Chile Argentina Asia Iraq India
Каждый XML-документ начинается с такой строки, встречая которую программа будет знать, что имеет дело именно с XML
Внешний блок
Вложенный блок (с отступом), содержащий информацию о материке Южная Америка
Блоки более глубокого уровня вложения, содержащие информацию о двух странах в Азии
XML дуже схожий на HTML, але в XML ви можете визначати власні теги.
Давайте обговоримо два терміни, значення яких ви повинні чітко уявляти для подальшого вивчення мови XML.
Елементи
XML-дані містяться в елементах. У елемента є ім'я і зазвичай є значення. У наведеному нижче прикладі елемент «Country» має значення «Argentina».
Як можна помітити, елемент обмежується відкриває і закриває тегами. Ім'я закриває тега повинно співпадати з ім'ям відкриваючого тега, але перед ім'ям додається коса риска "/".
Для запису елемента, що не має значення, допускається застосовувати один тег, в якому після імені елемента ставиться коса закриває риса.
elementname
<Country>
elementvalue
Argentina
</Country>
elementname
<Country />
Атрибути
У елемента можуть бути додаткові властивості, які необхідно описати. Наприклад, нам може знадобитися вказати столицю країни, для чого ми можемо створити атрибут елемента з ім'ям «capital». У наведеному нижче прикладі у вікні "Country» зі значенням «Argentina» атрибут «capital» має значення «Buenos Aires».
Людині дуже просто читати подібні документи, а оскільки вони мають чітку структуру, можна припустити, що і комп'ютер можна легко цьому навчити. Наприклад, скласти такий набір інструкцій: «Почати перегляд документа; при знаходженні символу" <"- читати ім'я елемента. При знаходженні символу ">" - читати значення елемента ... і так далі.
Приклад програми 15
Наступна програма зчитує географічні дані з XML-файла і відображає їх на формі. У ній використовуються три класи з простору імен System.Xml:
XmlDocument (створює об'єкт, що завантажує XML-дані для подальшої роботи);
XmlNodeList (запам'ятовує список елементів, що читаються з файлу);
XmlNode (запам'ятовує один XML-елемент).
Програма дозволяє користувачеві вводити так зване вираз xPath для вказівки того, які саме елементи необхідно витягти з XML-файла. Вираз xPath виду «/ / earth / continent / country» означає: «знайти всі елементи з ім'ям" country ", вкладені в елемент з ім'ям" continent ", вкладений у свою чергу в елемент з ім'ям" earth "».
using System; using System.Windows.Forms; using System.Drawing; using System.Xml; // Простір імен для роботи XML-даними using System.Xml.XPath; // Простір імен для роботи з виразами xPath class XmlRetriever : Form { ComboBox comboBox1; Button button1; ListBox listBox1; RichTextBox richTextBox1; XmlDocument xmlDoc; // Метод-конструктор нашего класса public XmlRetriever() { // Указываем высоту и заголовок окна this.Text = "XML Retrieval"; this.Size = new Size(400, 400); // Загружаем XML-файл с диска в находящийся в памяти объект XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load("../../data/earthData.xml"); // Готовим объект TextBox большого размера для вывода данных richTextBox1 = new RichTextBox(); richTextBox1.Dock = DockStyle.Top; richTextBox1.AcceptsTab = true; richTextBox1.Height = 180; richTextBox1.ReadOnly = true; richTextBox1.BackColor = Color.Silver; // Помещаем XML-данные в элемент TextBox і додаємо його на форму richTextBox1.Text = xmlDoc.OuterXml; this.Controls.Add(richTextBox1); // Добавляємо елемент управління ComboBox, позволяющий вводить // новое или выбирать существующее выражение Xpath. Добавим несколько // выражений XPath в качестве примера их написания. // (ComboBox представляет собой сочетание элементов TextBox и ListBox) comboBox1 = new ComboBox(); comboBox1.Location = new Point(0, 200); comboBox1.Width = 300; comboBox1.Items.Add("//Earth/Continent"); comboBox1.Items.Add("//Earth/Continent/Country"); comboBox1.Items.Add("//Earth/Continent/Country[@capital='Nairobi']"); comboBox1.SelectedIndex = 0; this.Controls.Add(comboBox1); // Добавляємо кнопку, нажатие которой приводит к отображению соответствующих элементов button1 = new Button(); button1.Text = "Get data"; button1.Location = new Point(310, 200); button1.Click += new EventHandler(Button1_Click); this.Controls.Add(button1); // Добавляємо элемент ListBox для отображения элементов listBox1 = new ListBox(); listBox1.Dock = DockStyle.Bottom; listBox1.Location = new Point(10, 10); this.Controls.Add(listBox1); } static void Main() { // Запускаємо новий екземпляр програми Windows Forms за допомогою вищеописаного класу Application.Run( new XmlRetriever() ); } // Обработчик события, срабатывающий при нажатии кнопки void Button1_Click(object sender, EventArgs e) { XmlNodeList xmlNodes; XmlNode xmlElement; string elementValue; // Используем блок try-catch для обработки исключений, вызванных ошибками // в выражениях XPath, и предотвращения сбоев приложения try { // Выбираем из XML-документа элементы, соответствующие // выражению XPath, заданному в ComboBox xmlNodes = xmlDoc.SelectNodes(comboBox1.Text); listBox1.Items.Clear(); // Производим циклический перебор найденных элементов, // добавляя каждый элемент в ListBox for (int i = 0; i < xmlNodes.Count; i++) { xmlElement = xmlNodes[i]; if (xmlElement.HasChildNodes) { elementValue = xmlElement.FirstChild.Value.Trim(); listBox1.Items.Add(elementValue); } } } catch (XPathException ex) { // При обнаружении ошибки XPath, Виводимо повідомлення и продолжаем работу программы MessageBox.Show ( "No matching data was found. Try another xPath expression.", "Error Encountered. " + ex.Message ); } } }
Програма відображає вихідний XML-файл в елементі керування RichTextBox. Далі під виразом xPath, що вводиться або вибираним користувачем, відображаються результати вибірки. Після запуску програми поекспериментуйте з введенням і вибором вираження xPath, після чого натисніть кнопку «Отримати дані».