Рисующее приложение в версии .NET, страница 5

Еще более сложное поведение компонента обнаруживается при связывании его с полноценным chm-файлом в формате HTML Help. Help-файл состоит из нескольких групп элементов: AssociateIndex, Find, Index, KeywordIndex, TableOfContents, Topic, которые перечислены в enum HelpNavigator. Каждому элементу управления на оконной форме может быть сопоставлено то или иное значение этого перечисления. Ключевое слово (keyword) или тема (topic) устанавливается методом SetHelpKeyword класса HelpProvider. Метод SetHelpNavigator класса HelpProvider устанавливает конкретную команду меню Help, которую надо выполнить в ответ на запрос справки об активном элементе управления. Эту функциональность мы не будем исследовать в данном разделе, но вы можете найти готовый chm-файл, например, в папке Samples установочного диска студии (”..\Samples\VCSharp\General\Scribble\help\scribble.chm”), задать этот файловый путь в строке свойства HelpNamespace компонентаhelpProvider и проверить его работу, запустив приложение и нажав клавишу F1. Вы увидите знакомый облик окна подсистемы Windows Help 1.0.

C#Help

В функциях обработки команд меню Help должен быть задействован класс System.Windows.Forms.Help. Он инкапсулирует функциональность подсистемы Windows HTML Help. Несмотря на то, что класс Help не является ненаследуемым (sealed), мы не можем создавать его объекты и должны вместо этого пользоваться статическими методами ShowHelp и ShowHelpIndex.

Архитектура Документ-Вид

Как вы помните из курса Visual C++ (MFC), MDI-приложения, обычно, выполняются в архитектуре Документ-Вид, которая представляет собой особую структуру данных и, как следствие, технологию разработки. Приведем краткое описание ее сути: объект класса приложения хранит список шаблонов документов, каждый шаблон хранит список документов своего типа, а каждый документ имеет список своих видов (child-окон главного окна). Главным моментом в этой архитектуре является тот факт, что один документ взаимодействует с несколькими своими видами, но каждый вид связан только с одним документом. В рамках архитектуры принято использовать следующие термины:

¨  документ — класс, инкапсулирующий данные документа. Он обеспечивает надежное хранение данных в архиве (файле, управляемом с помощью класса CArchive);

¨  вид — обозначает класс, производный от какого-либо оконного класса и инкапсулирующий функциональность окна, дочернего по отношению к главному окну. В нем в том или ином виде представлены данные документа.

В MFC существуют специальные классы CDocTemplate, CDocument и другие, которые содержит ряд полезных методов, облегчающих взаимодействие документа со своими видами. Например, документ содержит методы для управления списком своих видов, автоматичесую нумерацию окон видов, отслеживание изменений в данных документа и т.п. В рамках .NET Framework Classes нет классов, подобных перечисленным, но вместо этого есть ряд других, очень полезных классов, которые, в частности, реализуют функциональность динамических структур данных, таких как: стеки, списки, очереди, ассоциативные массивы или словари. В Microsoft-источниках эти структуры называются динамическими коллекциями объектов, а в большинстве других — контейнерами. Имея такие инструменты, довольно просто создать классы, которые будут выполнять многие из перечисленных функций, в том числе и многие функции класса CDocument.

Как было указано выше, в библиотеке классов .NET Framework класс Application является ненаследуемым (sealed), в отличие от класса CWinApp, он не содержит списка шаблонов документа, поэтому та модель, которая принята в MFC, не работает автоматически, но, как оказалось, она довольно просто имитируется. Временно не будем рассматривать разные шаблоны документов, будем считать, что каждый документ скроен по одному и тому же шаблону. Пусть каждый объект класса документа (назовем его DrawDoc) содержит:

¨  список (динамическую коллекцию) линий рисунка,

¨  список видов, изображающих содержимое документа (то есть линии рисунка),