C# для вундеркиндов. Часть 4. Программирование в .NET

реклама
C# для вундеркиндов. Часть 4. Программирование в .NET
Framework
Февраль 2007 г.
Программировать на языке C# без .NET Framework — это все равно, что писать ручкой без пасты. Как ни
води ею по бумаге, написать все равно ничего не удастся.
Так что же такое .NET Framework? Это платформа программирования, разработанная корпорацией Microsoft.
C# создавался как язык, предназначенный специально для .NET Framework. Платформа .NET Framework
состоит из двух частей:
1.
Во-первых, она включает огромную библиотеку классов, которые можно вызывать из программ на
C#. Это избавляет от необходимости писать все самому.
2.
Во-вторых, в ее состав входит среда выполнения, управляющая запуском и работой готовых
программ (это происходит незаметно — вам не нужно будет ни о чем беспокоиться).
При написании программы на языке 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 включен класс для быстрого написания консольных приложений.
Не стоит относиться снисходительно к консольным приложениям и считать их слишком примитивными. В
действительности оказывается, что настоящие программисты предпочитают не тратить усилия на
интерфейсные ухищрения и работают в основном с консольными приложениями.
Конечно, если вашей программой будет пользоваться кто-то еще, то вы, вероятно, окажете ему большую
услугу, сделав интерфейс чуть более дружественным, чем в консольном приложении.
Некоторые полезные методы
1.
Console.ReadLine — считывает строку символов, введенную с клавиатуры (или иного устройства
ввода)
2.
Console.Read — считывает число, введенное с клавиатуры (или иного устройства ввода)
3.
Console.WriteLine — выводит текст на экран (или иное устройство вывода), начиная с новой строки
4.
Console.Write — выводит на экран ряд символов без перехода на новую строку
Пример программы 1
Следующая программа просто выводит на экран слово «Yo!» и после этого ожидает нажатия клавиши ВВОД.
Код программы 1
using System;
class PleaseSayYo
{
static void Main()
{
// Выводим слово на экран
Console.Write("Yo!");
// Ожидаем нажатия клавиши ВВОД
Console.ReadLine();
}
}
Пример программы 2
Следующая программа:

просит пользователя ввести с клавиатуры слово;

спрашивает пользователя, сколько раз это слово должно быть выведено на экран;

выводит на экран введенное слово указанное количество раз, причем каждый раз с новой строки.
Код
программы 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);
}
// Ожидаем нажатия клавиши ВВОД
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. Все, что оно умеет, это создавать новую форму
и выводить определенный текст в заголовок окна.
Код
программы 3
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
Этот пример тоже достаточно прост, но здесь мы делаем шаг вперед — размещаем на форме кнопку
Код
программы 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
То, что мы поместили на форму кнопку, уже хорошо, но в предыдущем примере при нажатии на кнопку
ничего не происходит. Это неинтересно.
Нам нужно описать метод, который будет выполнять какое-либо действие при нажатии кнопки. Пусть при
этом будет меняться текст в заголовке окна. Поскольку такой метод отслеживает наступление некоторого
события (в нашем случае это нажатие кнопки) и затем каким-то образом обрабатывает его, он называется
«обработчик события». Кроме того, нам понадобится привязать обработчик события к соответствующему
событию, то есть к нажатию кнопки.
Код
программы 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.
Код
программы
6
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.
Код
программ
ы7
using
using
using
using
using
System;
System.Windows.Forms;
System.Drawing;
System.Data;
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 dimwitted";
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 прекрасно подходит для этой цели.
Код
программы 8
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» (Перевернуть)
позволяет получить ее зеркальное отражение по горизонтали.
Код
программы
9
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";
}
}
Теперь перейдем к примерам работы с векторной графикой — изображениям, составленным из отдельных
геометрических фигур.
Во всех этих примерах будет создаваться кнопка и обработчик событий, перехватывающий ее нажатие.
Работа с графикой будет начинаться только после нажатия кнопки.
Необходимо усвоить несколько важных принципов. Они вполне логичны, но не зная их, можно испытать
некоторые затруднения.
1.
В обычном мире чтобы нарисовать линию, окружность, прямоугольник или иную фигуру, необходимо
сначала выбрать карандаш нужного цвета и толщины.
Аналогично, для отрисовки на компьютере простейших фигур требуется предварительно создать
объект Pen (Перо). Например, с помощью данного фрагмента кода создается объект Pen, рисующий
зеленую линию толщиной 3 пикселя:
Pen myGreenPen = new Pen( Color.Green, 3 );
2.
Для рисования фигур с заливкой потребуется нечто вроде кисти с красками.
Для создания фигур с заливкой на компьютере требуется предварительно создать объект Brush
(Кисть) и выбрать цвет заливки. Имеются различные типы кисти. В следующем фрагменте кода
создается объект SolidBrush (Сплошная кисть) голубого цвета:
SolidBrush myBlueBrush = new SolidBrush(
Color.Blue );
Пример программы 10
В этой программе с помощью метода DrawSomeShapes рисуется линия, прямоугольник и эллипс
(«сплюснутая» окружность).
Код
программы
10
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.
Код
программы
11
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 (обитатели).
PLANET
PlanetName
DistanceFromSun
Inhabitants
Mercury
57909
Mercurians
Venus
108200
Venusians
Earth
149600
Earthlings
Mars
227940
Martians
Jupiter
778400
Jupiterians
Znock
7208100
Znockers
Saturn
1423600
Saturnians
Uranus
2867000
Uranians
Neptune
4488400
Neptunians
Pluto
5909600
Plutonians
Из приведенной таблицы видно, например, что Венера находится на расстоянии 108 200 тысяч километров от
Солнца, а существа, ее населяющие, именуются венерианцами.
Вот еще одна таблица, в которой содержатся сведения о ежегодной численности обитателей разных планет.
Это совершенно секретная информация, нигде ранее не обнародованная. Она была получена с
инопланетного звездолета, потерпевшего крушение в самой глубине пустыни Гоби. Это большая честь —
иметь возможность ознакомиться с ней. Очевидно, представители инопланетной цивилизации тоже
используют базы данных SQL Server Express, что и дало нам возможность привести здесь эти сведения в
качестве примера.
POPULATION
PlanetName
Year
Population
Mercury
2000
40000
Venus
2000
25
Earth
2000
6000000000
Mars
2000
325000
Jupiter
2000
8426300200
Znock
2000
550000
Saturn
2000
1000000
Uranus
2000
753425370
Neptune
2000
<NULL>
Pluto
2000
<NULL>
Mercury
2001
35000
Venus
2001
3
Earth
2001
6500000000
Mars
2001
326000
Jupiter
2001
8426300202
Znock
2001
8700
Saturn
2001
75000
Uranus
2001
844360002
Neptune
2001
<NULL>
Pluto
2001
<NULL>
Вы можете видеть, что в таблице есть две строки, касающиеся Венеры. Обратите внимание, что в 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 (звездочка * означает выбор всех столбцов
таблицы).
PlanetName
DistanceFromSun
Inhabitants
Mercury
57909
Mercurians
Venus
108200
Venusians
Earth
149600
Earthlings
Mars
227940
Martians
Jupiter
778400
Jupiterians
Znock
7208100
Znockers
Saturn
1423600
Saturnians
Uranus
2867000
Uranians
Neptune
4488400
Neptunians
Pluto
5909600
Plutonians
SELECT PlanetName, Inhabitants
FROM PLANET
Этот запрос возвращает столбцы «PlanetName» и «Inhabitants» со всеми строками из таблицы PLANET.
PlanetName
Inhabitants
Mercury
Mercurians
Venus
Venusians
Earth
Earthlings
Mars
Martians
Jupiter
Jupiterians
Znock
Znockers
Saturn
Saturnians
Uranus
Uranians
Neptune
Neptunians
Pluto
Plutonians
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.
PlanetName
Population
Mercury
40000
Venus
25
Neptune
<NULL>
Pluto
<NULL>
Mercury
35000
Venus
3
Saturn
75000
Neptune
<NULL>
Pluto
<NULL>
Как правило, оператор INSERT записывается следующим образом:
INSERT INTO <таблица базы данных, к которой добавляются строки>
(<столбцы, в которые будут добавляться значения>)
INSERT INTO PLANET
(PlanetName, DistanceFromSun, Inhabitants)
VALUES
('Fluff', 23500000, 'Fluffies')
Оператор INSERT добавляет в таблицу PLANET новую строку. Он не возвращает какого-либо результата в
программу, но ради наглядности мы покажем, какой вид примет таблица после его выполнения.
PLANET
PlanetName
DistanceFromSun
Inhabitants
Mercury
57909
Mercurians
Venus
108200
Venusians
Earth
149600
Earthlings
Mars
227940
Martians
Jupiter
778400
Jupiterians
Znock
7208100
Znockers
Saturn
1423600
Saturnians
Uranus
2867000
Uranians
Neptune
4488400
Neptunians
Pluto
5909600
Plutonians
Fluff
23500000
Fluffies
Как правило, оператор UPDATE записывается следующим образом:
UPDATE < таблица базы данных, в которую вносятся изменения>
SET <столбцы, в которые необходимо внести изменения> = <новые значения>
UPDATE PLANET
SET PlanetName='Stuff', Inhabitants='Stuffies'
WHERE PlanetName='Fluff'
Оператор изменяет некоторые значения в строке, в которой столбец PlanetName имеет значение «Fluff» и
тоже не возвращает какой-либо результат в программу. Далее показано, какой вид примет таблица после его
выполнения.
PLANET
PlanetName
DistanceFromSun
Inhabitants
Mercury
57909
Mercurians
Venus
108200
Venusians
Earth
149600
Earthlings
Mars
227940
Martians
Jupiter
778400
Jupiterians
Znock
7208100
Znockers
Saturn
1423600
Saturnians
Uranus
2867000
Uranians
Neptune
4488400
Neptunians
Pluto
5909600
Plutonians
Stuff
23500000
Stuffies
Связи и объединение
Если вы обратите внимание, то заметите, что между таблицами PLANET и POPULATION существует связь. В
обеих таблицах есть столбец с именем «PlanetName». Мы говорим, что эти таблицы связаны по столбцу
«PlanetName». Благодаря этой связи можно собрать всю информацию об определенной планете.
Например, можно выбрать из обеих таблиц все строки, касающиеся Венеры ...
PLANET
PlanetName
Venus
POPULATION
DistanceFromSun
108200
и объединить их в одну большую таблицу ...
Inhabitants
PlanetName
Year
Population
Venusians
Venus
2000
25
Venus
2001
3
SELECT *
FROM PLANET INNER JOIN POPULATION ON
PLANET.PlanetName=POPULATION.planetName
WHERE PlanetName='Venus'
PLANETS_AND_POPULATIO
N
PlanetName
DistanceFromSun
Inhabitants
PlanetName
Year
Population
Venus
108200
Venusians
Venus
2000
25
Venus
108200
Venusians
Venus
2001
3
Используемая СУБД
Существуют причины, по которым в некоторых ситуациях для работы с определенной СУБД требуются особые
программные решения. Так, в среде .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.
Если у вас установлен и готов к работе Microsoft SQL Server Express, используйте примеры 12a, 13a
и 14a. В противном случае, если у вас возникают проблемы с запуском этих программ, можно
воспользоваться примерами 12b, 13b и 14b, аналогичными по сути, но не требующими установки
СУБД.
Обращение к базе данных из программы на языке C#
В следующих образцах программ на C# будут применены классы SqlConnection и SqlCommand,
обеспечивающие взаимодействие с базой данных SQL Server Express под названием «Planets». Эти классы
предназначены специально для работы с базами данных Microsoft SQL Server любой версии. Далее мы будем
работать с данными двумя различными способами:
1.
С использованием класса SqlDataReader, который обеспечивает разнообразные возможности
программного управления базой данных, позволяя построчно перебирать данные и выполнять
различные действия над выбранными значениями.
2.
С использованием классов 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;
Затем произведите замену классов для работы с данными, как указано ниже:
SQL Server
General Databases
SqlCommand
OleDbCommand
SqlCommandBuilder
OleDbCommandBuilder
SqlDataAdapter
OleDbDataAdapter
SqlConnection
OleDbConnection
Введение
Классы пространства имен System.Xml позволяют работать с XML-данными разными способами. Наиболее
часто выполняются следующие задачи:

открытие XML-документа;

чтение фрагмента XML-данных для извлечения некоторых значений;

сохранение XML-файла на диск.
Краткое введение в XML
Язык XML получил в наши дни крайне широкое распространение, и, скорее всего, вы уже слышали о нем.
XML представляет собой прекрасный пример языка, рассчитанного как на человеческое, так и на
компьютерное восприятие. Как правило, данные, с которыми работают различные вычислительные системы,
кажутся обычным людям китайской грамотой, но XML-документы записываются в виде обычного текста.
Например, можно составить XML-документ для хранения на диске некоторых географических данных:
<?xml
version="1.0" encoding="utf-8" ?>
South
America
Chile
Каждый XML-документ начинается с такой строки,
встречая которую программа будет знать, что имеет
дело именно с XML
Внешний блок
Вложенный блок (с отступом), содержащий
информацию о материке Южная Америка
Блоки более глубокого уровня вложения,
содержащие информацию о двух странах в Азии
Argentina
Asia
Iraq
India
XML весьма похож на HTML, но в XML вы можете определять собственные теги.
Давайте обсудим два термина, значение которых вы должны ясно представлять для дальнейшего изучения
языка XML.
Элементы
XML-данные содержатся в элементах. У элемента есть имя и обычно имеется значение. В приведенном ниже
примере элемент «Country» имеет значение «Argentina».
elementname
elementvalue
<Country>
Argentina
</Country>
Как можно заметить, элемент ограничивается открывающим и закрывающим тегами. Имя закрывающего тега
должно совпадать с именем открывающего тега, но перед именем добавляется косая черта "/".
Для записи элемента, не имеющего значения, допускается применять один тег, в котором после имени
элемента ставится косая закрывающая черта.
elementname
<Country />
Атрибуты
У элемента могут быть дополнительные свойства, которые необходимо описать. Например, нам может
потребоваться указать столицу страны, для чего мы можем создать атрибут элемента с именем «capital». В
приведенном ниже примере у элемента «Country» со значением «Argentina» атрибут «capital» имеет значение
«Buenos Aires».
elementname
attributename
<Country
capital
attributevalue
=
elementvalue
"Buenos Aires"
>
Argentina
</Country>
Человеку очень просто читать подобные документы, а поскольку они имеют четкую структуру, можно
предположить, что и компьютер можно легко этому научить. Например, составить такой набор инструкций:
«Начать просмотр документа; при нахождении символа "<" — читать имя элемента. При нахождении символа
">" — читать значение элемента ... и так далее.
Пример программы 15
Следующая программа считывает географические данные из XML-файла и отображает их на форме.
В ней используются три класса из пространства имен System.Xml:

XmlDocument (создает объект, загружающий XML-данные для последующей работы);

XmlNodeList (запоминает список элементов, читаемых из файла);

XmlNode (запоминает один XML-элемент).
Программа позволяет пользователю вводить так называемое выражение xPath для указания того, какие
именно элементы необходимо извлечь из XML-файла. Выражение xPath вида «//earth/continent/country»
означает: «найти все элементы с именем "country", вложенные в элемент с именем "continent", вложенный в
свою очередь в элемент с именем "earth"».
Код
программ
ы 15
using
using
using
using
System;
System.Windows.Forms;
System.Drawing;
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. Добавим несколько
// выражений
их написания.
// (ComboBox
сочетание элементов TextBox и ListBox)
элемент управления
выбирать существующее
XPath в качестве примера
представляет собой
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, после чего нажмите кнопку
«Получить данные».
Скачать