Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный_практикум.doc
Скачиваний:
73
Добавлен:
15.11.2019
Размер:
45.35 Mб
Скачать

7. Модификация приложения Windows Forms: вкладка «Векторные часы»

Данная вкладка отображает текущее время на стилизованном «аналоговом» циферблате (без использования изображений и сторонних ресурсов). В ней использован большой набор примитивов: прямоугольники, эллипсы и отрезки прямых. Для расчёта их координат используются не геометрические преобразования GDI+, а простые вычисления. Что действительно заслуживает внимания, так это отображение стрелок часов. Каждая стрелка рисуется всего одним вызовом метода DrawLine!

Для часиков создаём четвёртую вкладку tabPage4 со свойствами:

TabPage:

Text:

Векторные часы

Cursor:

AppStarting

Добавляем на форму таймер (Timer) со свойствами:

Timer:

(Name):

timer1

Interval:

1000

Инициализируем событие первого таймера Tick:

private void timer1_Tick(object sender, EventArgs e)

{

tabPage4.Text = "Векторные часы: " + DateTime.Now.ToLongTimeString();

Invalidate();

}

Инициализируем событие Selected для главного элемента TabControl со следующим кодом:

private void TB_Main_Selected(object sender, TabControlEventArgs e)

{

if (e.TabPage.Name == tabPage4.Name) timer1.Enabled = true;

else timer1.Enabled = false;

}

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

Инициализируем событие загрузки формы Load:

private void LWP19Main_Load(object sender, EventArgs e)

{

SetStyle(ControlStyles.AllPaintingInWmPaint, true);

SetStyle(ControlStyles.DoubleBuffer, true);

SetStyle(ControlStyles.UserPaint, true);

}

И, наконец, инициализируем событие Paint вкладки tabPage4, а также дополнительный метод:

private Point RadialPoint(int radius, int seconds)

{

Point ptCenter = new Point(tabPage4.ClientRectangle.Width / 2, tabPage4.ClientRectangle.Height / 2);

double angle = -((seconds - 15) % 60) * Math.PI / 30; // Вычисляем угол на "окружности" (шаг)

Point ret = new Point(

ptCenter.X + (int)(radius * Math.Cos(angle)),

ptCenter.Y - (int)(radius * Math.Sin(angle)));

return ret;

}

private void tabPage4_Paint(object sender, PaintEventArgs e)

{

// Создаём объект часов

DateTime dt = DateTime.Now;

Graphics g = e.Graphics;

g.SmoothingMode = SmoothingMode.HighQuality;

// Вычисляем центральную точку для циферблата

Point ptCenter = new Point(tabPage4.ClientRectangle.Width / 2, tabPage4.ClientRectangle.Height / 2);

// Вычисляем радиус циферблата на основе размеров вкладки

int radius = Math.Min(tabPage4.ClientRectangle.Width, tabPage4.ClientRectangle.Height) / 2;

using (LinearGradientBrush br = new LinearGradientBrush(tabPage4.ClientRectangle, Color.White, Color.Azure, LinearGradientMode.BackwardDiagonal))

{

//br.SetSigmaBellShape(.5f, 1.0f);

// Заполняем циферблат градиентом

g.FillEllipse(br, ptCenter.X - radius, ptCenter.Y - radius, radius * 2, radius * 2);

}

// Рисуем эллипс цифербалата

using (Pen pen = new Pen(Color.Black))

g.DrawEllipse(pen, ptCenter.X - radius, ptCenter.Y - radius, radius * 2, radius * 2);

// Цикл минуты

for (int minute = 0; minute < 60; minute++)

{

Point pt = RadialPoint(radius - 10, minute);

using (SolidBrush br = new SolidBrush(Color.Black))

{

if ((minute % 5) == 0)

g.FillRectangle(br, pt.X - 3, pt.Y - 3, 6, 6);

else

g.FillRectangle(br, pt.X - 1, pt.Y - 1, 2, 2);

}

}

// Рисуем стрелку часов (от центра до позиции на циферблате)

using (Pen pen = new Pen(Color.Black, 8))

{

pen.StartCap = LineCap.Flat;

pen.EndCap = LineCap.DiamondAnchor;

float[] compVals = new float[] { 0.0f, 0.2f, 0.5f, 0.7f, 0.9f, 1.0f };

pen.CompoundArray = compVals;

g.DrawLine(pen, RadialPoint(15, 30 + dt.Hour * 5 + dt.Minute / 12), RadialPoint((int)(radius * 0.75), dt.Hour * 5 + dt.Minute / 12));

}

// Рисуем минутную стрелку

using (Pen pen = new Pen(Color.FromArgb(100, 0, 0, 0), 6))

{

pen.StartCap = LineCap.RoundAnchor;

pen.EndCap = LineCap.Round;

g.DrawLine(pen, RadialPoint(15, 30 + dt.Minute), RadialPoint((int)(radius * 0.8), dt.Minute));

}

// Русуем секундную стрелку

using (Pen pen = new Pen(Color.FromArgb(50, 150, 50, 25), 4))

{

pen.CustomEndCap = new AdjustableArrowCap(4, 6, true);

g.DrawLine(pen, RadialPoint(20, dt.Second + 30), RadialPoint(radius - 2, dt.Second));

}

using (SolidBrush br = new SolidBrush(Color.FromArgb(100, Color.Wheat)))

g.FillEllipse(br, ptCenter.X - 5, ptCenter.Y - 5, 10, 10);

}

Компилируем (Debug) и запускаем. Переходим на закладку «Векторные часы», чем запускаем таймер, заголовок вкладки будет отображать текущее время, а на самой вкладке видим круглые стрелочные часы собранные из примитивов. Мило!