Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование / Программирование в среде Visual C# (Часть 2).pdf
Скачиваний:
164
Добавлен:
27.05.2015
Размер:
1.41 Mб
Скачать

2.3 Простейшие классы

Задание: Элементом списка является пара целых числа. Отображение элемента осуществляется в виде строки, например, «10/15». Считая первое число делимым, а второе – делителем, требуется найти сумму результатов делений.

Будем считать, что форма называется Main_F (изменено свойство Name у формы).

Для решения поставленной задачи потребуются компоненты:

First_L класса Label для подписи компонента First_TB;

First_TB класса TextBox для ввода первого числа добавляемого эле-

мента;

Second_L класса Label для подписи компонента Second_TB;

Second_TB класса TextBox для ввода второго числа добавляемого эле-

мента;

Spisok_L класса Label для подписи компонента Spisok_LB;

Spisok_LB класса ListBox для хранения и отображения введенных

элементов;

Add_B класса Button для активизации добавления элемента;

Del_B класса Button для активизации удаления элемента;

Calc_B класса Button для активизации расчета;

Result_L класса Label для подписи компонента Result_TB;

Result_TB класса TextBox для вывода результата расчета.

Установим следующие значения свойств компонентов (таблица 3):

Таблица 3 – Значения свойств компонентов для примера выполнения задания по работе с простейшими классами

Компонент.Свойство

Значение

First_L.Text

П&ервое число добавляемого элемента

Second_L.Text

Второе число доба&вляемого элемента

Spisok_L.Text

Спи&сок элементов

Add_B.Text

Доб&авить

Del_B.Text

Удал&ить

Calc_B.Text

Рас&чет

Result_L.Text

Ре&зультат

Result_TB.ReadOnly

true

 

 

20

Для описания класса потребуется отдельный модуль. Добавим его в программу через меню «Проект → Добавить новый элемент → Файл с текстом программы».

При описании класса (назовем его TElement) необходимо, помимо указания его полей, переопределить метод ToString, чтобы компонент класса ListBox мог отображать экземпляры класса правильным образом. Класс должен быть описан в том же пространстве имен, что и основная программа. Опишем класс следующим образом:

namespace ...

{

public class TElement

{

public int First,Second;

public override string ToString()

{

return First.ToString() + "/" + Second.ToString();

}

}

}

Опишем событие Click кнопки Add_B:

private void Add_B_Click(object sender, EventArgs e)

{

/* Перед работой с экземпляром класса, его нужно создать */ TElement Element = new TElement();

/* Заполнение свойств класса введенными пользователем данными */

Element.First = Convert.ToInt32(First_TB.Text); Element.Second = Convert.ToInt32(Second_TB.Text); /* Добавление в список нового элемента */ Spisok_LB.Items.Add(Element);

}

Опишем событие Click кнопки Del_B:

private void Del_B_Click(object sender, EventArgs e)

{

/* Проверка, выбран ли элемент в списке */

if (Spisok_LB.SelectedIndex != -1) // Элемент выбран Spisok_LB.Items.RemoveAt(Spisok_LB.SelectedIndex);

else // Элемент не выбран

{Вывод окна сообщений с необходимым текстом} MessageBox.Show("Не выбран элемент в списке", "Информация");

}

21

Опишем событие Click кнопки Calc_B:

private void Calc_B_Click(object sender, EventArgs e)

{

/* Проверка, введены ли данные */

if (Spisok_LB.Items.Count > 0) // Элементы введены

{

/* Обнуление переменной-накопителя */ double Sum = 0;

/* Организация перебора всех введенных элементов */ for (int i=0; i<Spisok_LB.Items.Count; i++)

{

/* Получение элемента, связанного с текущей строкой */ TElement Element = Spisok_LB.Items[i] as TElement;

/* Суммирование результатов деления для текущего

элемента. При делении требуется преобразование

одного из операндов к вещественному типу, т.к. иначе выполнится целочисленное деление */

Sum += (double)Element.First/Element.Second;

}

/* Вывод результата */ Result_TB.Text = Sum.ToString();

}

else // Элементы не введены

/* Вывод окна сообщений с необходимым текстом */ MessageBox.Show("Не введены элементы", "Информация");

}

Внешний вид и пример работы программы показаны на рисунке 4.

Рисунок 4 – Внешний вид и пример работы программы, реализующей работу с простейшими классами

22

2.4 Графика

Задание: Фигура представляет собой квадрат красного цвета с черной границей и двумя диагональными линиями синего цвета. Диагональные линии не доходят до углов на 1/10 ширины квадрата. Начальное расположение – низцентр поверхности рисования. Поверхность рисования квадратная. Движение

– по линиям, соединяющим центры сторон поверхности рисования по часовой стрелке.

Будем считать, что поверхность, по которой будет осуществляться движение фигуры, имеет белый цвет и размер 300 300 точек. Фигура осуществляет 20 единичных перемещений в секунду.

Для решения поставленной задачи потребуются компоненты:

Image_PB класса PictureBox для построения изображения;

Move_T класса Timer для обеспечения перемещения фигуры.

Установим следующие значения свойств компонентов (таблица 4):

Таблица 4 – Значения свойств компонентов для примера выполнения задания по работе с графикой

Компонент.Свойство Значение

Image_PB.Size.Height 300

Image_PB.Size.Width 300

Image_PB.BackColor White

Move_T.Enabled False

Move_T.Interval 50

Для удобства управления фигурой создадим класс TFigure в отдельном модуле, который добавим в программу через меню «Проект → Добавить новый элемент → Файл с текстом программы».

Данный класс должен иметь базовую точку рисования и базовый размер. На основе этих параметров должны рассчитываться все остальные координаты и размеры элементов фигуры. В качестве базовой точки взят левый верхний угол квадрата, а в качестве базового размера – его сторона.

Класс будет включать следующие элементы:

X, Y. Текущие координаты верхнего левого угла фигуры;

dX, dY. Текущее приращение по координатам при единичном переме-

щении;

Size. Размер фигуры;

cPictureBox. Ссылка на компонент, на котором строится изображе-

ние;

cPen. Инструмент рисования линий. При создании устанавливается в черный цвет;

23

cBrush. Инструмент заливки. При создании устанавливается в красный

цвет;

TFigure. Конструктор, вызываемый при создании экземпляра класса;

~TFigure. Деструктор, вызываемый при разрушении экземпляра класса;

Show. Метод рисования фигуры;

Hide. Метод стирания фигуры;

Move. Метод перемещения фигуры.

Реализацию класса выполним следующим образом:

class TFigure

{

int X,Y,dX,dY; int Size;

PictureBox cPictureBox;

Pen cPen = new Pen(Color.Black);

SolidBrush cBrush = new SolidBrush(Color.Red);

public TFigure(int NewX, int NewY, int NewSize, PictureBox NewPictureBox)

{

/* Установка начальных характеристик фигуры */ X = NewX;

Y = NewY;

dx = -1; // Движение влево dY = -1; // Движение вверх

Size = NewSize;

cPictureBox = NewPictureBox;

Show(); // Вывод фигуры на поверхности рисования

}

~TFigure()

{

/* Разрушение объектов, созданных в классе */ cPen.Dispose();

cBrush.Dispose();

}

public void Show()

{

/* Установка цвета рисования границы и заливки фигуры */ cPen.Color = Color.Black;

cBrush.Color = Color.Red;

/* Получение поверхности рисования */

Graphics cGraphics = Graphics.FromImage(cPictureBox.Image); /* Рисование прямоугольника и его заливка */ cGraphics.DrawRectangle(cPen, X, Y, Size, Size); cGraphics.FillRectangle(cBrush, X+1, Y+1, Size-1, Size-1); /* Установка цвета диагональных линий */

cPen.Color = Color.Blue;

24

/* Рисование диагональных линий. Координаты точек линии определяем в долях от основного размера Size */

cGraphics.DrawLine(cPen, X+Size/10, Y+Size/10, X+Size-Size/10, Y+Size-Size/10);

cGraphics.DrawLine(cPen, X+Size-Size/10, Y+Size/10, X+Size/10, Y+Size-Size/10);

/* Обновление компонента вывода изображения */ cPictureBox.Refresh();

/* Разрушение созданной поверхности рисования */ cGraphics.Dispose();

}

public void Hide()

{

/* Получение поверхности рисования */

Graphics cGraphics = Graphics.FromImage(cPictureBox.Image); /* Стирание фигуры должно осуществляться путем установки

цвета заливки в цвет фона поверхности рисования и отрисовки наибольшей составляющей фигуры */

cBrush.Color = Color.White; cGraphics.FillRectangle(cBrush, X, Y, Size, Size); /* Обновление компонента вывода изображения */ cPictureBox.Refresh();

/* Разрушение созданной поверхности рисования */ cGraphics.Dispose();

}

/* Процедура единичного перемещения включает определение

новой вероятной позиции фигуры, проверку выхода фигуры за границы области рисования и, если необходимо, корректировку движения, расчет новых координат */

public void Move()

{

Hide(); // Стирание фигуры в старом месте

int Temp = X+dX;//Расчет вероятной позиции фигуры по оси Х /* Проверка выхода за границы по оси Х. В случае выхода –

смена направления движения по оси Х */ if (Temp < 0 || Temp+Size > MaxSize)

dX = -dX;

X += dX; // Расчет новой позиции фигуры по оси Х

/* Далее аналогичные действия для оси Y */ Temp = Y+dY;

if (Temp < 0 || Temp+Size > MaxSize) dY = -dY;

Y += dY;

Show(); // Отображение фигуры в новом месте

}

}

25

Класс должен быть описан в том же пространстве имен, что и основная программа. Кроме того, потребуется использование пространств имен для обращения к классам, используемым при рисовании:

using System;

using System.Drawing; using System.Windows.Forms;

namespace ...

{

...

}

Описание переменной выполним в классе основной формы:

TFigure Figure;

Создание фигуры в момент загрузки программы и ее разрушение в момент завершения опишем следующим образом:

private void Form1_Load(object sender, EventArgs e)

{

/* Будем считать, что фигура имеет размер 1/4 от ширины

поверхности рисования */ int Temp = Image_PB.Width / 4;

/* Создание картинки в компоненте Image_PB */ Image_PB.Image = new Bitmap(Image_PB.Width,

 

Image_PB.Height);

/* Создание экземпляра класса

с указанием начальных значений

параметров фигуры */

 

 

Figure = new TFigure(

 

 

Image_PB.Width/2-Temp/2, //

Координата Х

Image_PB.Height-Temp,

//

Координата Y

Temp,

//

Размер фигуры

Image_PB);

//

Ссылка на компонент

Move_T.Enabled = true;

//

Включение таймера

}

private void Form1_FormClosed(object sender, FormClosedEventArgs e)

{

Move_T.Enabled = false;

//

Выключение таймера

Figure.Hide();

//

Стирание фигуры

}

При срабатывании таймера, производится единичное перемещение фигуры:

private void Move_T_Tick(object sender, EventArgs e)

{

Figure.Move();

}

26