Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
STIP_Labs_2015_16(C#).doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
4.42 Mб
Скачать

6.2.Рисование простейших фигур на холсте

Шаг 1. Создайте каркас приложения WPF, выполнив команду FileNewProjectVisual C# Windows WPF Application. Предположим, что вы присвоили проекту имя TestCanvas.

Теперь в окно приложения (файл Window1.xaml) хитростью (или силой) затащите управляющий элемент Canvas из окна Toolbox. Распяльте его так, чтобы он занимал практически всю клиентскую область окна.

Уловчитесь также добавить обработчики событий Loaded и MouseLeftButtonDown для окна Window1. В результате этих воистину героических усилий содержимое файла Window1.xaml должно стать примерно таким:

<Window x:Class="TestCanvas.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Window1" Height="300" Width="300" Loaded="Window_Loaded"

MouseLeftButtonDown="Window_MouseLeftButtonDown">

<Grid Width="273">

<Canvas Margin="12,0,0,12" Name="canvas1" />

</Grid>

</Window>

Красиво? Наш холст Microsoft нарекла именем canvas1. Не нравится – измените!

Шаг 2. Добавим несколько строк кода исключительно ради забавы (хвайл Window1.xaml.cs):

Шаг 3. Если вам удастся компилировать и запустить приложение на выполнение, то пощелкайте ЛКМ в клиентской области окна и проследите за последствиями. Если в точке щелчка мышью появляется эллипс, а предыдущее его изображение исчезает, значит, так оно и должно быть. Интересно, да? Как так получается, что эллипс скачет?

Рис. 1. Рисование эллипса по щелчку ЛКМ

Шаг 4. «Лучшее – враг хорошего». Или это не всегда так? Имея ввиду дальнейшее «секретное» совершенствование приложения, попробуем создать свой собственный класс «эллипс» с тем чтобы в дальнейшем можно было создавать произвольное число эллипсов в окне и заставлять их двигаться по командам пользователя или какого-нибудь метода. Итак, проанализируйте и воспроизведите в лучшем виде следующий программный код, который, конечно, не является совершенным. Результат работы новой версии приложения будет тот же, что и предыдущей (версии).

Результат работы этого варианта программы будет таким же, как и предыдущего, но мы люди предусмотрительные и думаем о будущем, т.е. о возможности рисования сразу нескольких эллипсов и ... не только.

Шаг 5. Научим эллипс перемещаться с использованием события, посылаемого классу MyEllipse по щелчку ПКМ в области окна. Приведенный ниже вариант программы обладает следующей функциональностью: щелчок ЛКМ в области окна приводит к выводу фигуры эллипс, а щелчок ПКМ в области окна – к перемещению этого эллипса по горизонтали в сторону увеличения х-координаты эллипса. Собственно само перемещение выполняет следующий метод класса MyEllipse:

public void EventHandler()

{

m_elpdata.X += 1;

Show();

}

Изменения, внесенные в программу, выделены комментариями «действие n», где n =1..4. Суть их сводится к тому, что в программу добавлен класс MyEvent_1, метод On_Command() которого запускает событие (event), обработчик которого EventHandler() «перемещает» эллипс. Последовательность действий программы удобно проследить с помощью трассировки в отладчике. О событиях можно почитать в разделе 10.7 [8]

private void Window_MouseLeftButtonDown(object sender,

MouseButtonEventArgs e)

{

EllipseData elp_Data = new EllipseData();

elp_Data.rX = 10;

elp_Data.rY = 3;

Point pnt = new Point(e.GetPosition(canvas1).X - elp_Data.rX,

e.GetPosition(canvas1).Y - elp_Data.rY);

elp_Data.X = pnt.X;

elp_Data.Y = pnt.Y;

elp_Data.thickness = 2;

elp.elpdata = elp_Data;

elp.Show();

}

//////////// действие 4 //////////

private void Window_MouseRightButtonDown(object sender,

MouseButtonEventArgs e)

{

evt_1.On_Command(); // посылаем таракану команду "вперед"

// elp.EventHandler(); /* можно и так, но это слишком просто*/

}

//////////// конец действия 4 //////////

}

//////////// действие 2 //////////

delegate void CockRoach();

class MyEvent_1

{

// Объявляем событие

public event CockRoach CR_GO;

// Объявим метод для запуска события

public void On_Command() { CR_GO(); }

}

//////////// конец действия 2 //////////

public class MyEllipse /* В качестве базового невозможно использовать

класс Ellipse, так как он "запечатанный" - sealed */

{

Ellipse m_elp;

Point pnt;

EllipseData m_elpdata;

public EllipseData elpdata

{

get { return m_elpdata; }

set { m_elpdata = value; }

}

//////////// действие 1 //////////

/*EventHandler() - обработчик события, которое мы будем посылать

эллипсу из другого класса MyEvent_1 в методе

Window_MouseRightButtonDown() */

public void EventHandler()

{

m_elpdata.X += 1;

Show();

}

//////////// конец действия 1 //////////

}

}

Шаг 7. Как эллипс гоняется за мышкой. Найдите проект ..\STIP\ProjectExamples\AnimateEllipse(движ-эллипс) изучите и исследуйте его с помощью трассировки. Разберитесь, какова последовательность работы каркаса приложения: с чего начинается выполнение приложения, как создается главное и единственное окно и т.д. Естественно, изучите код, который отображает эллипс и заставляет его перемещаться. Используемые пространства имен и классы обсуждаются в работе [9], которую вы можете найти в каталоге ..\STIP\C_Sharp_DOC\.

Если вам захочется использовать таймер, то вот простейший способ использования таймера, включающий лямбда-выражение вместо делегата:

using System;

using System.Threading;

namespace TimerTest

{

class Program

{

private static Timer timer;

private static void Main()

{

timer = new Timer(_=>OnCallBack(), null,

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]