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

2.8 Древовидные структуры

Задание: Структура «дерева» имеет вид, описанный в таблице 12.

Таблица 12 – Структура «дерева»

Уро-

Описание элементов

Строка отображаемой

вень

«дерева»

информации

1

список разделов

'Это корень дерева'

2

шифр раздела

'Наименование раздела: '+

 

 

+<наименование раздела>

3

наименование раздела

'Шифр раздела: '+<шифр раздела>

 

список книг

 

4

наименование книги

'Наименование раздела: '+

 

 

+<наименование раздела>

5

автор

'Наименование книги: '+

 

количество страниц

+<наименование книги>

Примечание – Вместо строки в угловых скобках (< >) выводить реальные данные; знак «+» не выводится

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

TextBox.

При анализе предметной области можно выделить два класса: раздел и книга.

Опишем реализацию классов TBook (книга) и TSection (раздел) в отдельном модуле, который добавим в программу через меню «Проект → Добавить новый элемент → Файл с текстом программы». Классы должны быть описаны в том же пространстве имен, что и основная программа. Также должно быть подключено необходимое пространство имен.

using System.Collections.Generic;

namespace ...

{

public class TBook

{

public string Name, Autor; public int Count;

}

45

public class TSection

{

public string Name, Shift; /* Список книг раздела */

public List<TBook> Books = new List<TBook>();

}

}

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

Catalog_L класса Label для подписи компонента Catalog_TV;

Catalog_TV класса TreeView для отображения «дерева»;

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

Change_B класса Button для активизации редактирования выбранного

элемента;

Del_B класса Button для активизации удаления выбранного элемента;

Info_L класса Label для подписи компонента Info_TB;

Info_TB класса TextBox для вывода информации для выбранного эле-

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

Таблица 13 – Значения свойств компонентов основной формы для примера программы, использующей древовидную структуру

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

Значение

Catalog_L.Text

Структура &каталога

Add_B.Text

Доб&авить

Change_B.Text

И&зменить

Del_B.Text

Уда&лить

Info_TB.ReadOnly

true

 

 

Info_L.Text

Информац&ия

Создадим, с помощью строенного редактора, в компоненте Catalog_TV «корень дерева» в виде строки «Список разделов».

На форме диалогового окна работы с разделом (Section_F) потребуются компоненты:

Shifr_L класса Label для подписи компонента Shifr_TB;

Shifr_TB класса TextBox для ввода шифра раздела;

Name_L класса Label для подписи компонента Name_TB;

Name_TB класса TextBox для ввода наименования раздела;

Ok_B класса Button для подтверждения добавления или редактирова-

ния;

Cancel_B класса Button для отмены добавления или редактирования.

46

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

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

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

Значение

Section_F.FormBorderStyle

FixedDialog

 

 

Section_F.AcceptButton

Ok_B

 

 

Section_F.CancelButton

Cancel_B

 

 

Section_F.MinimizeBox

false

 

 

Section_F.MaximizeBox

false

 

 

Section_F.ShowInTaskbar

false

 

 

Shifr_L.Text

Ши&фр

Name_L.Text

Наи&менование

Ok_B.Text

Ok

Ok_B.DialogResult

OK

 

 

Cancel_B.Text

Отм&ена

Cancel_B.DialogResult

Cancel

 

 

На форме диалогового окна работы с книгой (Book_F) потребуются компоненты:

Name_L класса Label для подписи компонента Name_TB;

Name_TB класса TextBox для ввода наименования книги;

Autor_L класса Label для подписи компонента Autor_TB;

Autor_TB класса TextBox для ввода автора книги;

Count_L класса Label для подписи компонента Count_NUD;

Count_NUD класса NumericUpDown для ввода количества страниц кни-

ги;

Ok_B класса Button для подтверждения добавления или редактирова-

ния;

Cancel_B класса Button для отмены добавления или редактирования. Установим следующие значения свойств компонентов (таблица 15).

Будем считать, что максимальное количество страниц у книги – 5000:

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

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

Book_F.FormBorderStyle FixedDialog

Book_F.AcceptButton Ok_B

Book_F.CancelButton Cancel_B

Book_F.MinimizeBox false

47

Продолжение таблицы 15

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

Значение

Book_F.MaximizeBox

false

 

 

Book_F.ShowInTaskbar

false

 

 

Name_L.Text

Наи&менование

Autor_L.Text

А&втор

Count_NUD.Minimum

1

 

 

Count_NUD.Maximum

5000

 

 

Count_NUD.Value

1

 

 

Count_L.Text

Количество &страниц

Ok_B.Text

Ok

Ok_B.DialogResult

OK

 

 

Cancel_B.Text

Отм&ена

Cancel_B.DialogResult

Cancel

 

 

Опишем событие Shown формы Section_F:

private void Section_F_Shown(object sender, EventArgs e)

{

Shifr_TB.Focus();

}

Опишем событие FormClosing формы Section_F:

private void Section_F_FormClosing(object sender, FormClosingEventArgs e)

{

/* Алгоритм проверки правильности ввода приводился в предыдущих заданиях */

}

Аналогично описываются события для формы Book_F.

В классе TMain_F опишем поле для хранения коллекции разделов:

List<TSection> Catalog = new List<TSection>();

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

private void Add_B_Click(object sender, EventArgs e)

{

/* Проверка, что что-либо выбрано */ if (Catalog_TV.SelectedNode != null)

{

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

имеет уровень 1 */

if (Catalog_TV.SelectedNode.Level == 0)

// Выбран список

{

// разделов

Section_F Dialog = new Section_F();

 

48

/* Установка заголовка формы и значений “по умолчанию” для всех полей ввода */

...;

if (Dialog.ShowDialog() == DialogResult.OK)

{

TSection Section = new TSection(); Section.Shift = Dialog.Shifr_TB.Text.Trim(); Section.Name = Dialog.Name_TB.Text.Trim();

/* Созданный раздел необходимо добавить в список разделов */

Catalog.Add(Section);

/* Добавление элемента дерева для шифра и запоминание его во временную переменную для последующей работы с ним */

TreeNode TempNode = Catalog_TV.SelectedNode.Nodes.Add (Section.Shift);

/* Добавление элементов дерева для наименования раздела и списка книг */

TempNode.Nodes.Add("Наименование: "+Section.Name); TempNode.Nodes.Add("Список книг");

}

}

else

{Выбран список книг, если элемент имеет уровень 3 и является вторым в списке элементов родителя}

if (Catalog_TV.SelectedNode.Level == 2 && Catalog_TV.SelectedNode.Index == 1)

{

Book_F Dialog = new Book_F();

/* Установка заголовка формы и значений “по умолчанию” для всех полей ввода */

...;

if (Dialog.ShowDialog() == DialogResult.OK)

{

TBook Book = new TBook();

/* Заполнение свойств книги и */

...; /* Для получения раздела, в который добавляется

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

TSection Section = Catalog.ElementAt( Catalog_TV.SelectedNode.Parent.Index);

Section.Books.Add(Book);

/* Добавление элементов дерева */

...;

}

}

else

MessageBox.Show("Добавление возможно только в списки разделов или книг", "Информация");

}

else

49

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

}

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

private void Change_B_Click(object sender, EventArgs e)

{

if (Catalog_TV.SelectedNode != null)

{

/* Редактирование возможно, если выбран раздел (уровень 2) или книга (уровень 4) */

if (Catalog_TV.SelectedNode.Level == 1 || Catalog_TV.SelectedNode.Level == 3)

{

if (Catalog_TV.SelectedNode.Level == 1) // Выбран раздел

{

/* Получение выбранного раздела */ TSection Section = Catalog.ElementAt(

Catalog_TV.SelectedNode.Index); Section_F Dialog = new Section_F();

...; // Подготовка диалогового окна к работе if (Dialog.ShowDialog() == DialogResult.OK)

{

...; // Изменение свойств раздела на новые

/* Изменение всех элементов дерева, связанных

с разделом */

Catalog_TV.SelectedNode.Text = Section.Shift; Catalog_TV.SelectedNode.Nodes[0].Text =

"Наименование: "+Section.Name;

}

}

else

{// Выбрана книга /* Для получения раздела, в который добавляется

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

TSection Section = Catalog.ElementAt( Catalog_TV.SelectedNode.Parent.Parent.Index);

/* Получение выбранной книги */ TBook Book = Section.Books.ElementAt(

Catalog_TV.SelectedNode.Index);

Book_F Dialog = new Book_F();

/* Выполнение действий, аналогичных изменению раздела */

...;

}

}

else

MessageBox.Show("Изменить можно только раздел или книгу", "Информация");

50

}

else

MessageBox.Show("Выберите раздел или книгу для изменения", "Информация");

}

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

private void Del_B_Click(object sender, EventArgs e)

{

if (Catalog_TV.SelectedNode != null)

{

/* Удаление возможно, если выбран раздел (уровень 2) или

книга (уровень 4) */

if (Catalog_TV.SelectedNode.Level==1 || Catalog_TV.SelectedNode.Level==3)

{

if (Catalog_TV.SelectedNode.Level == 1) // Раздел

/* Удаление выбранного раздела из списка разделов */ Catalog.RemoveAt(Catalog_TV.SelectedNode.Index);

else // Книга

{

/* Получение раздела, к которому относится книга */ TSection Section = Catalog.ElementAt(

Catalog_TV.SelectedNode.Parent.Parent.Index); /* Удаление выбранной книги из раздела */

Section.Books.RemoveAt(Catalog_TV.SelectedNode.Index);

}

/* Удаление элемента “дерева” со всеми потомками */ Catalog_TV.SelectedNode.Remove();

}

else

MessageBox.Show("Удалить можно только раздел или книгу", "Информация");

}

else

MessageBox.Show("Выберите раздел или книгу для удаления", "Информация");

}

Опишем событие AfterSelect компонента Catalog_TV:

private void Catalog_TV_AfterSelect(object sender, TreeViewEventArgs e)

{

TSection Section;

/* Определение уровня выбранного элемента */ switch (Catalog_TV.SelectedNode.Level)

{

case 0:

/* Для каждого уровня требуется вывести свою

информацию и определить доступность действий */

51

Info_TB.Text = "Это корень дерева";

Add_B.Enabled = true; Change_B.Enabled = false; Del_B.Enabled = false; break;

case 1:

...; case 2:

...; case 3:

...; case 4:

...;

}

}

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

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

52