Kitabı oku: «Справочник Жаркова по проектированию и программированию искусственного интеллекта. Том 7: Программирование на Visual C# искусственного интеллекта. Издание 2», sayfa 2

Yazı tipi:

2.3. Методика проектирования формы

Для предварительного (пока без внесения элементов управления с панели инструментов Toolbox, рис. 2.3) визуального графического проектирования формы выполняем следующие типичные шаги инструкции.

1. Панель Properties (Свойства) со свойствами формы Form1 (рис. 2.4) мы можем вызвать (если она не появилась автоматически) при помощи команды View, Properties Window и разместить в виде отдельной панели в любом месте экрана, а можем сделать в виде вкладки более общей панели.

Если в панели Properties нет заголовка Form1, то просто щёлкаем внутри формы, или там же делаем правый щелчок и в контекстном меню выбираем Properties. В панели Properties далее мы всегда будем подразумевать одноименную вкладку Properties (если не оговаривается особо, например, вкладка событий Events). После изменения (заданного по умолчанию) свойства мы должны дать программе команду внести это изменение в форму или элемент управления; для этого щёлкаем по выделенному имени свойства или нажимаем клавишу Enter.

Если не видна форма (диалоговая панель) в режиме проектирования, то на рабочем столе щёлкаем вкладку Form1.cs [Design] или в панели Solution Explorer (Исследователь-Проводник Решения) дважды щёлкаем пункт Form1.cs.

2. В панели Properties с заголовком Form1 (рис. 2.4) щёлкаем (выделяем) слово Font и появившуюся кнопку с тремя точками. Мы увидим панель Font (рис. 2.4).

3. В панели Font (Шрифт) устанавливаем, например, шрифт Times New Roman и размер (Size) 14 для текста на форме и для текста на элементах управления, которые мы будем переносить на форму с панели Toolbox. В панели Font щёлкаем OK.

4. Чтобы изменить заголовок формы, в панели Properties в свойстве Text вместо слова Form1 записываем (или вставляем из буфера обмена: правый щелчок, Paste), например, Calculator; щёлкаем по слову Text (или нажимаем клавишу Enter), рис. 2.4.

5. При помощи свойства BackColor (рис. 2.4) мы можем установить (вместо установленного по умолчанию цвета Control) из списка другой цвет клиентской области Form1. Перечень этих цветов показан в наших предыдущих книгах [Литература]. Напомним, что в клиентскую область не входит верхняя полоска с текстом и граница формы.

6. При помощи свойства BackgroundImage (Фон), рис. 2.4, в качестве фона мы можем установить имеющийся у нас рисунок (форматов (.bmp), (.jpg), (.gif) и др.) или даже несколько рисунков, которые с заданным нами интервалом времени будут поочередно сменять друг друга в режиме анимации; затем на этом изменяющемся фоне можно размещать элементы управления (например, TextBox и Button) и компоненты (например, Timer), как показано в наших предыдущих книгах [Литература].

7. Напомним, что на инструментальной панели Toolbox (рис. 2.3) имеются элементы управления Windows Forms и специализированные компоненты. Для создания пользовательского интерфейса нашего приложения сначала на форме можно разместить элемент управления в виде рамки группы GroupBox, чтобы затем внутри этой рамки располагать другие элементы. Для этого на панели инструментов Toolbox (рис. 2.3) щёлкаем элемент GroupBox (рамка группы). Выполняем щелчок на форме. Чтобы изменить название groupBox1, в панели Properties в свойстве Text вместо groupBox1 записываем (или вставляем из буфера обмена: правый щелчок, Paste), например, Сложение чисел (Addition of numbers); щёлкаем по выделенному слову Text (или нажимаем клавишу Enter) Затем в панели Properties можно установить другие свойства рамки группы.

8. Аналогично размещаем первое окно текста TextBox (для ввода первого слагаемого); в панели Properties появляется новый заголовок textBox1; для удаления (в окне) надписи textBox1, в панели Properties в свойстве Text стираем текст (или последовательно нажимаем две клавиши пробела и Enter).

9. Размещаем второе окно для второго слагаемого и третье окно для суммы.

10. Чтобы пользователю было понятно, что означает каждое окно, около каждого окна вводим надпись Label. Например, первую надпись label1 мы можем изменить или сразу с клавиатуры, или в панели Properties с заголовком label1 в свойстве Text вместо label1 записываем (или вставляем из буфера обмена: правый щелчок, Paste), например, число 1 (number 1).

11. Аналогично записываем текст выше второго и третьего окон, а между первым и вторым окнами – знак суммы “+”.

12. Чтобы получить результат сложения после щелчка кнопки со знаком равенства “=”, вводим эту кнопку на форму по обычной схеме: на панели Toolbox выбираем Button; щёлкаем на форме; надпись button1 мы можем изменить или сразу с клавиатуры, или в панели Properties в свойстве Text вместо button1 записываем (или вставляем из буфера обмена: правый щелчок, Paste), например, знак равенства “=”; щёлкаем по выделенному слову Text (или нажимаем клавишу Enter).

В классе Form1 на вкладке Class View появились эти элементы управления. Форма приняла окончательный внешний вид (рис. 2.6).

Отметим, что на приведённых рисунках видны отличия новой платформы Visual Studio от предыдущих версий этой же платформы, которые подробно описаны в наших предыдущих книгах из списка литературы и с сайта .

Важно отметить, что все программы, которые далее мы будем разрабатывать, применимы для всех версий и редакций среды разработки (платформы) Visual Studio.

Рис. 2.3. Панель инструментов Toolbox. Рис. 2.4. Панели Solution Explorer и Properties.


Рис. 2.5. В панели Font устанавливаем шрифт.



Рис. 2.6. Форма после графического (визуального) проектирования.

2.4. Код программы

Теперь в файл Form1.cs нам необходимо написать нашу часть кода для сложения двух чисел на форме. Для связывания с кодом элементов управления и компонентов используются методы, которые называются обработчиками событий и вызываются после двойного щелчка по имени соответствующего метода на вкладке Events (со значком в виде молнии) на панели Properties (рис. 2.4). Например, обработчик события в виде щелчка кнопки “=” (рис. 2.6) вызывается после двойного щелчка по имени метода Click на вкладке Events панели Properties. Но так как щелчок кнопки является наиболее распространённым событием, то он задан как событие по умолчанию и поэтому может быть также вызван двойным щелчком кнопки в режиме проектирования. Выполняем это. Появляется файл Form1.cs со следующим автоматически сгенерированным кодом:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

namespace Calculator

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

}

}

И в этот файл Form1.cs уже автоматически добавлен следующий шаблон метода для обработки события в виде щелчка кнопки:

private void button1_Click(object sender, EventArgs e)

{


}

Так как выше в коде уже подключено корневое пространство имён (using System;), то имя System (и другие подключённые имена) далее в нашем коде мы можем не записывать.

В данный шаблон можно записать много вариантов кода для выполнения простых арифметических операций.

Чтобы лучше понять синтаксис визуального (с использованием элементов управления, например, TextBox) программирования, приведём четыре (по мере усложнения) варианта кода для сложения двух чисел.

Первый вариант – с тремя переменными:

Листинг 2.1. Наш основной код с тремя переменными.

double a, b, c;

a = Convert.ToDouble(textBox1.Text);

b = Convert.ToDouble(textBox2.Text);

c = a + b;

textBox3.Text = c.ToString();

Второй вариант – с двумя переменными:


double a, b;

a = Convert.ToDouble(textBox1.Text);

b = Convert.ToDouble(textBox2.Text);

textBox3.Text = (a + b).ToString();

Третий вариант – с одной переменной:

double a;

a = Convert.ToDouble(textBox1.Text);

textBox3.Text = (a +

Convert.ToDouble(textBox2.Text)).ToString();

Четвёртый вариант – без использования переменных:


textBox3.Text = (Convert.ToDouble(textBox1.Text) +

Convert.ToDouble(textBox2.Text)).ToString();

По этой методике можно записывать код для выполнения различных математических операций. Подробные объяснения этой программы (какие пространства имён, классы, методы и свойства мы использовали) даны в наших книгах [Литература].

После построения программы (щёлкаем Build, Build Selection или значок с изображением вертикальных стрелок) мы увидим в выходном окне Output сообщение компилятора C# или об успешном построении, или об ошибке (если при вводе нашего кода был введен не тот символ) с указанием типа ошибки и номера строки кода с ошибкой. Ошибку стандартно исправляем, снова строим программу, и так до тех пор, пока не получим сообщение компилятора без ошибок и предупреждений.

Если ошибок нет, то в меню Debug выбираем Start Without Debugging (или щёлкаем по значку с соответствующим изображением).

На рабочем столе поверх формы в режиме проектирования (рис. 2.6) появляется форма в режиме выполнения (рис. 2.7), которую можно захватить мышью за верхнюю полоску и передвинуть в удобное место.

2.5. Выполнение расчётов

Выполняем типичный расчёт: 1,1 + 2,2 = 3,3 и результат показываем на рис. 2.7.




Рис. 2.7. Пример сложения двух чисел.

На рис. 2.7 видно, что и в первые два окна мы записываем десятичную дробь с запятой, и результат получаем в виде десятичной дроби с запятой. Следовательно, эти варианты кода на листинге 2.1 соответствуют российским (и международным) стандартам, когда десятичная дробь записывается с запятой. Поэтому в дальнейшем мы будем применять именно эти варианты кода.

Аналогично выполняется суммирование различных чисел: целых и дробных, положительных и отрицательных. Таким образом, мы выполнили первый традиционный расчёт сложения двух чисел и теперь можем разрабатывать методики для решения более сложных задач при помощи языка программирования Visual C# (в последующих главах).

2.6. Техническая характеристика калькулятора

Исследуем возможности созданного нами калькулятора с целью применения его на практике. Попытаемся ввести в первое окно максимально большое число, состоящее, например, из двоек ( цифр 2). Оказывается, в окно можно вводить большое количества цифр (сколько поместится в окне, каким бы большим мы его не делали), но учитываться в расчёте будет только ограниченное количество этих цифр. Для примера вводим двадцать двоек. Во второе окно также записываем цифры, например, двадцать троек (цифр 3). После щелчка кнопки “=” результат виден на рис. 2.8.



Рис. 2.8. Результат сложения двух больших чисел.

В числе с плавающей точкой (точнее, запятой), например, 5,555555555555557E+19 (рис. 2.8) цифры перед символом E называются мантиссой, а после E – порядком. Следовательно, в нашем калькуляторе максимальное количество разрядов мантиссы, дающих правильное значение числа, – пятнадцать (последняя пятнадцатая цифра 6 на рис. 2.8 округлена и определяет погрешность вычислений). Если после каждого щелчка кнопки “=” постепенно увеличивать количество цифр в первом или во втором окне, то увидим, что тридцать вторая (и далее) цифра уже не увеличивает порядок суммарного числа в третьем окне. Следовательно, в нашем калькуляторе максимальный порядок числа – тридцать один (31).

Логичным завершением исследования возможностей нашего калькулятора явится его следующая краткая техническая характеристика.

1. Система счисления вещественных чисел при вводе и выводе – десятичная.

2. Максимальное количество разрядов мантиссы числа – пятнадцать (15).

3. Максимальный порядок числа – тридцать один (31).

4. Диапазон вычислений числа “x” по модулю |x|

1*10E-031 <= |x| <= 9.99999999999999*10E+031.

5. Форма представления запятой (точки):

в диапазоне

1 <= |x| <= 999999999999999

– естественная;


в диапазонах

1*10E-031 <= |x| < 1

и

999999999999999 < |x| <= 9.99999999999999*10E+031

– плавающая.

Как видно из этой технической характеристики, созданный нами калькулятор в чем-то превосходит настольные калькуляторы и Windows-калькуляторы, а в чем-то уступает.

Но главное достоинство состоит в том, что наш калькулятор является открытой вычислительной системой и, если в этом есть необходимость, аналогично (как для сложения и вычитания) по разработанной выше методике мы можем вводить в наше приложение-калькулятор выполнение других арифметических и математических операций с различным количеством методов, и постепенно создавать все более сложную нашу персональную (или корпоративную) вычислительную систему для решения именно наших конкретных задач.

Теперь разработаем методику создания анимации, на основании которой разработаем первый эффект анимации для данной Form1.

2.7. Общая методика создания анимации

Разработаем общую методику создания анимации в различных приложениях и апробируем её на примере создания мигающего заголовка формы, точнее, создания чередующегося заголовка, когда одно название заголовка будем сменяться другим названием с заданной нами частотой (или интервалом времени). По этой методике анимационный заголовок можно встроить в любое приложение.

Для создания любой анимации необходимо ввести компонент Timer по схеме:

1. На панели инструментов Toolbox щёлкаем строку Timer (рис. 2.3).

2. Щёлкаем на форме.

Ниже Form1 появляется значок с надписью timer1 (рис. 2.9), который можно захватить мышью и перенести в другое место.

Отметим, что в отличие от элементов управления компоненты располагаются вне формы и поэтому на форме в режиме выполнения не видны.

3. В панели Properties с заголовком timer1:

в свойстве Enabled вместо False выбираем True (рис. 2.10);

в свойстве Interval вместо заданных по умолчанию 100 миллисекунд задаём, например, значение 500 миллисекунд (напомним, что 1000 миллисекунд равны 1 секунде).

Естественно, эти установки можно выполнить не только в панели Properties, но и в программе, например, при помощи следующего кода.

Листинг 2.2. Метод для включения таймера и задания интервала времени.

private void InitializeTimer()

{

//We turn on the timer:

timer1.Enabled = true;

//We generate the Tick event through each Interval of time:

timer1.Interval = 500;

}





Рис. 2.9. Значок компонента Timer. Рис. 2.10. Панель Properties.

Теперь в режиме выполнения проекта с интервалом в эти 500 миллисекунд (или 0,5 секунды) будет генерироваться запрограммированное нами событие Tick и выполняться при помощи метода timer1_Tick (см. ниже листинг 2.3), а именно, в данной главе будет мигать заголовок формы.

Следовательно, мы закончили визуальную разработку анимационного эффекта и теперь нам необходимо написать код программы. Этот код может иметь много вариантов.

Рассмотрим, например, три варианта:

1) анимация выполняется безостановочно столько, сколько выполняется наше приложение, и анимационный объект (текст, кнопка, цвет и т.д.) изменяется за каждый интервал времени Interval;

2) анимация выполняется безостановочно столько, сколько выполняется наше приложение, но анимационный объект изменяется не за каждый интервал времени Interval, а через заданное нами число интервалов N_Interval ;

3) анимация выполняется столько времени, какое число интервалов времени мы задали, и после этого времени анимационный объект останавливается в заданном нами положении.

Сначала изучим первый вариант, когда анимация выполняется безостановочно за каждый интервал времени Interval. Для этого дважды щёлкаем значок timer1 (рис. 2.8) в режиме проектирования (или в панели Properties на вкладке Events дважды щёлкаем по имени единственного события Tick).

Появляется файл Form1.cs с автоматически сгенерированным шаблоном метода, выше которого объявляем булеву переменную, а в шаблон записываем такой код.

Листинг 2.3. Код для создания анимации. Вариант 1.

//We declare the Boolean myText variable and appropriate it

//”false” (by default too "false"):

bool myText = false;

private void timer1_Tick(object sender, EventArgs e)

{

//We set the alternation of " Calculator " and

//" Calculator with animation ":

if (myText == false)

{

this.Text = " Calculator ";

//We change the myText value to opposite:

myText = true; //or so: myText =! myText;

}

else

{

this.Text = " Calculator with animation ";

//We change the myText value to opposite:

myText = false; //or so: myText =! myText;

}

}

В этом коде использовано правило переноса текста с одной строки на другую.

Теперь изучим второй вариант, когда анимация выполняется безостановочно столько, сколько выполняется наше приложение, но анимационный объект изменяется не за каждый интервал времени Interval, а через заданное нами число интервалов N_Interval. Для этого в файле Form1.cs выше того же (что и в предыдущем варианте) автоматически сгенерированного шаблона метода объявляем переменные, а в шаблон записываем код, как показано на следующем листинге.

Листинг 2.4. Код для создания анимации. Вариант 2.

//We declare the counter of number of intervals

//and set its initial value:

private int counter = 0; //by default too it is equal to 0.

//We declare and set the number N_Interval of intervals,

//after which one text is replaced by another:

private int N_Interval = 3;

private void timer1_Tick(object sender, EventArgs e)

{

//We check, value of the counter

//equally or yet is not present to number N_Interval of

//intervals,

//after which one text is replaced by another:

if (counter >= N_Interval)

{

//If value of the counter collected and is equal

//N_Interval, we output other text:

this.Text = "Calculator";

//We nullify the value of the counter again:

counter = 0;

}

else

{

//If value of the counter did not collect yet

//and N_Interval is not equal,

//that we output the first text:

this.Text = "Calculator with animation";

//We increase value of the counter on 1:

counter = counter + 1;

}

}

И наконец, изучим третий вариант, когда анимация выполняется столько времени, какое число интервалов времени N_Interval_Stop мы задали, и после этого времени анимационный объект останавливается в заданном нами положении. Для этого в файле Form1.cs выше того же (что и в предыдущем варианте) автоматически сгенерированного шаблона метода объявляем большее число переменных, а в шаблон записываем более общий код, как показано на следующем листинге.

Листинг 2.5. Код для создания анимации. Вариант 3.

//We declare the counter of number of intervals

//and set its initial value:

private int counter = 0;

//We declare and set the number N_Interval of intervals,

//after which one text is replaced by another:

private int N_Interval = 3;

//We declare and nullify the i_Interval_Stop counter,

//which calculates the number of intervals

//to an animation stop:

private int i_Interval_Stop = 0;

//We declare and set the number N_Interval_Stop of intervals,

//on reaching which animation stops:

private int N_Interval_Stop = 10;

private void timer1_Tick(object sender, EventArgs e)

{

//Value of the i_Interval_Stop counter,

//which calculates the number of intervals

//to an animation stop, we increase on 1:

i_Interval_Stop = i_Interval_Stop + 1;

//We check the number i_Interval_Stop of intervals,

//on reaching which animation stops:

if (i_Interval_Stop >= N_Interval_Stop)

timer1.Enabled = false;

//We check, value of the counter

//equally or yet is not present to number N_Interval of

//intervals,

//after which one text is replaced by another:

if (counter >= N_Interval)

{

//If value of the counter collected and is equal

//N_Interval, we output other text:

this.Text = "Calculator";

//We nullify value of the counter again:

counter = 0;

}

else

{

//If value of the counter did not collect yet

//and N_Interval is not equal,

//that we output the first text:

this.Text = "Calculator with animation";

//We increase value of the counter on 1:

counter = counter + 1;

}

}

Так как здесь мы впервые применили метод timer1_Tick, а далее постоянно будем его применять, то дадим краткие пояснения.

Автоматически сгенерированный заголовок метода

private void timer1_Tick(object sender, EventArgs e)

говорит нам о том, что метод timer1_Tick обрабатывает (Handles) событие Tick, периодически (с заданным интервалом при помощи свойства Interval) возбуждаемое объектом (таймером) timer1. В строке (bool myText = false;) мы объявляем булеву глобальную переменную myText выше метода timer1_Tick. Если бы переменную myText мы задали в виде локальной переменной внутри метода timer1_Tick, то при каждом новом вызове (с заданным интервалом) этого метода timer1_Tick значение переменной myText оставалось бы неизменным, и анимации не получилось бы.

По какому-либо одному варианту кода, например, по первому варианту строим программу и запускаем на выполнение обычным образом: Build, Build Selection; Debug, Start Without Debugging.

В ответ Visual C# выполняет программу и на рабочий стол выводит форму в режиме выполнения. На этой форме с заданной нами частотой в 500 миллисекунд (или 0,5 секунды) заголовок “Калькулятор (Calculator)” сменяется на “Калькулятор с анимацией (Calculator with animation)” (рис. 2.10), и таким образом создаётся эффект анимации.



Рис. 2.10. Форма с анимационным заголовком.

Если на листингах 2.3 – 2.5 вместо слова "Калькулятор (Calculator)" записать оператор "" (т.е. удалить слово "Калькулятор (Calculator)"), то будет появляться и исчезать только второй заголовок формы "Калькулятор с анимацией (Calculator with animation)", и этот заголовок будет только мигать (без замены текста) с заданной частотой. Далее на этом калькуляторе можно выполнять описанные выше расчёты (рис. 2.10).

Аналогично создаётся анимация по второму варианту (листинг 2.4) и третьему варианту (листинг 2.5); каждый вариант имеет свои особенности. И читатель может выбрать наиболее понравившийся вариант анимации. Мы же в дальнейшем будем применять, в основном, первый вариант, как наиболее простой.

Следовательно, мы закончили разработку методики создания трёх вариантов анимации на примере анимационного заголовка формы. Подчеркнем, что мы разработали именно общую методику создания анимации, так как если в программах на листингах 2.3 – 2.5 вместо ключевого слова this записать значение свойства Name для какого-нибудь элемента управления (label1, button1 и т.д.), то мы получим эффект анимации для текста на этом элементе управления.