Пользовательский элемент управления. Создание клиентского приложения. Развитие серверного проекта, страница 3

¨  В окне Solution Explorer выделите имя проекта Plot, вызовите контекстное меню и дайте команду Properties.

¨  В окне диалога Plot Property Pages раскройте узел Configuration Properties и выделите строку Debugging.

¨  В правом окне найдите группу команд под заголовком Start Action и выделите строку Debug Mode.

¨  В окне выпадающего списка выберите режим отладки Program и нажмите кнопку Apply. Если вы забудете это сделать, то следующая команда Start Application для выбора клиентского приложения будет недоступна.

¨  Перейдите в строку Start Application и с помощью файлового диалога укажите путь к исполняемому модулю клиентского приложения PlotClient.exe (мы его уже создали) и нажмите кнопку OK.

¨  Проверьте, запускается ли клиент в момент запуска сервера. Для этого нажмите Ctrl+F5 и убедитесь, что создается окно клиента с уже внедренным в него окном сервера. Последнее окно можно увидеть, только если его фон отличается от фона клиентской формы.

Развитие серверного проекта

Развитие сервера начнем с того, что введем в него реакцию на сообщение WM_PAINT (перерисовка клиенской области окна). Оказывается, это действие в рамках .NET Framework можно выполнить двумя способами. Первый состоит в том, что в классе формы переопределяется виртуальная функция OnPaint, (она унаследована от класса Control), а второй — в том, что непосредственно вводится реакция на событие Paint. Это делается в режиме дизайна.

Для реализации первого способа откройте окно ClassView, прогуляйтесь по дереву родителей (Bases and Intrfaces) в поисках класса Control. Надеюсь, вы догадались, что начинать надо с нашего класса PlotControl. Затем найдите саму функцию OnPaint и дайте команду Add4Override.

Для реализации второго способа откройте файл Plot.cs в режиме дизайна, нажмите кнопку Events, расположенную в заголовке окна Properties, и дважды щелкните по строке Paint, что приведет к созданию функции обработки этого события. Если вы выполнили оба алгоритма, то в классе PlotControl будут два метода, реагирующие на сообщение WM_PAINT. Полезно сравнить их.

protected override void OnPaint (PaintEventArgs e) { base.OnPaint (e); }

private void PlotControl_Paint (object sender, PaintEventArgs e) { }

Переопределенная версия виртуальной функции, как видите, имеет описатель override. Какая же из двух функций и когда будет работать? Для ответа на этот вопрос проведем эксперимент. Вставим в тела обеих функций код, который выводит проверочный текст. Например:

protected override void OnPaint (PaintEventArgs e)

{

e.Graphics.DrawString ("Работает виртуальный OnPaint !",Font, Brushes.Red,50,20);

base.OnPaint (e);

}

private void PlotControl_Paint(object sender, PaintEventArgs e)

{

e.Graphics.DrawString ("Работает Paint Handler!", Font, Brushes.Blue, 50, 50);

}

Расставьте точки останова (F9) и запустите отладчик (F5). Сформулируйте ответ на вопрос: "Какая из двух функций вызывается первой?" После того, как вы получите ответ, оставьте лишь одну функцию и удалите другую. Если будете удалять PlotControl_Paint, то не забудьте, что обработчик события Paint отличется от override-версии OnPaint тем, что вставляет делегата PlotControl_Paint в коллекцию делегатов события Paint. Поэтому удаления самой функции обработки недостаточно. Нужно удалить еще одну строку кода. Какую? Если не догадались, то компилятор "подскажет".

Внесите в класс сервера (PlotControl) исправления, которые сделают его неработоспособным до тех пор, пока мы не создадим и не отладим вспомогательный класс Graph. Последний будет по умолчанию выводить в окно сервера график некоторой функции. Наличие этого графика в окне внедренного элемента надо воспринимать как свидетельство того, что сервер жив, здоров и готов выводить графики других функций. Данные для новых графиков, как вы помните, должны генерироваться клиентским приложением. Новая версия класса PlotControl приведена ниже. При внесении изменений будьте осторожны и не удалите стандартный код, присутствующий в любой форме (методы Dispose и InitializeComponent).