Шаг 2. Перерисовка башни при изменении количества блоков




Описание проекта

Проект TOWERS представляет собой компью­терную реализацию известной логической задачи "Ханойские башни". Эта задача состоит в следующем: имеются три колышка, на один из которых нанизано (в порядке уменьшения размера) несколько дисков, образующих "башню"; требуется переместить всю башню на один из пустых колышков, пользуясь другим пустым колышком как вспомогательным. Переносить можно по одно­му диску, причем больший диск нельзя помещать на меньший. Для решения задачи с N дисками минимальное число переносов равно 2N-1.

В приложении TOWERS вместо колышков используются компоненты-контейнеры GroupBox, а вместо дисков перемещаются прямоугольные блоки (компоненты Label), создаваемые непосредственно в ходе выполнения про­граммы. Перемещение блоков реализуется с помощью механизма drag&drop. Предусматриваются средства проверки правильности решения, а также демо-режим, показывающий, в каком порядке надо перемещать блоки, чтобы решить задачу.

Шаг 1. Создание начальной позиции

После создания проекта TOWERS разместите в форме Form1 три компонента типа GroupBox (они получат имена groupBox1 — groupBox3) и компонент типа NumericUpDown (он получит имя numeгicUpDown1). Настройте свойства формы Form1 и добавленных компонентов:

Компонент Свойство Значение
Form1 Text Ханойские башни
MaximizeBox False
FormBorderStyle FixedSingle
StartPosition CenterScreen
groupBox1 Text Начальная позиция
groupBox2 пустая строка
groupBox3 пустая строка
numericUpDown Minimum  
Maximum  
Value  

 


 

Расположите компоненты в соответствии с рис. 1:

Рис. 1. Вид формы Form1 для проекта TOWERS на начальном этапе разработки

Определите обработчик события Load для формы Form1.

private void Forml_Load(object sender, EventArgs e)

{

Random r = new Random();

int n = (int) numericUpDown1.Value, w = groupBox1.Width, h = groupBox1.Height;

for (int i = 0; i < n; i++)

{

Label lb = new Label();

lb.Parent = groupBox1;

lb.BorderStyle = BorderStyle .FixedSingle;

lb.Size = new Size((w - 10) * (n - i) / n, (h - 15) / n);

lb. Location =new Point((w - lb.Width) / 2, h - 2 - (i + 1) * lb.Height);

lb.BackColor = Color.FromArgb(r.Next(256), r.Next(256), r.Next (256));

}

}

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

Результат: при запуске программы на компоненте groupBox1 рисуется башня из четырех разноцветных блоков — компонентов типа Label (цвет блоков определяется случайным образом).

Шаг 2. Перерисовка башни при изменении количества блоков

Определите обработчик события ValueChanged для компонента numericUpDown1.

private void numericUpDownl_ValueChanged(object sender, EventArgs e)

{

Form1_Load (this, null);

}

Результат: при изменении значения компонента numericUpDown1 создается новая башня с указанным числом блоков.

Ошибка: новая башня рисуется подстарой.

Исправление: в класс Form1 добавьте новый метод label_Dispose:

private void label_Dispose (GroupBox gb)

{

for (int i = gb.Controls.Count - 1; i >= 0; i--)

gb.Controls [i].Dispose();

}

В начало метода numericUpDownl_ValueChanged вставьте оператор:

label_Dispose(groupBox1);

Результат: теперь все блоки старой башни исчезают с экрана, а также осво­бождают свои ресурсы (благодаря вызову метода Dispose).

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

Исправление: в методе Form1_Load переместите оператор

lb.Parent = groupBox1;

в конец цикла (после оператора, определяющего фоновый цвет метки).

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



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-08-07 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: