В
прошлой статье я попытался рассказать, как нужно рисовать
собственные ASP.NET серверные элементы управления. И обещал продолжить
рассказ о создании элемента управления. И хоть и прошло уже очень много
времени, но обещания нужно выполнять, что я и попытаюсь сделать :). В
этой статье разговор пойдет о создании событий в серверном элементе
управления, генерации постбека и вызове обработчиков событий. Итак что
же нужно для того, чтобы наш пейджер начал реально работать? Не так уж и
много на самом деле - нужно всего лишь описать делегат, определить
событие в элементе управления и, при необходимости, описать структуру,
передающую данные в обработчик события. И начнем мы с объявления
делегата.
Делегат по сути является указателем на функцию в терминах С++. Для
делегатов, определяющих события в серверных контролах, накладываются
дополнительные ограничения - такой делегат должен принимать 2 параметра,
первый из которых должен быть типа object (в нем передается ссылка на
объект, сгенерировавший данное событие), а второй - типа EventArgs (в
этом параметре передается дополнительная информация, связанная с
вызываемым событием). Класс EventArgs - базовый класс для всех
классов, передающих дополнительную информацию, сам по себе он не
содержит никаких свойств для передачи информации и используется в
случаях, когда событие просто объявляет о том, что оно произошло
(например событие Click серверного элемента управления Button). В нашем
же случае необходимо в событии передать дополнительные данные - новый
номер страницы. Посему для передачи этих данных определим класс -
наследник класса EventArgs.
public class PagerEventArgs : EventArgs
{
public int SelectedPage;
public PagerEventArgs(int SelectedPage)
{
this.SelectedPage = SelectedPage;
}
}
После чего объявление делегата для нашего события не представляет
никакой проблемы:
public delegate void PagerEventHandler(Object sender, PagerEventArgs e);
И, соответственно, добавим свойство этого типа в наш класс.
public class Pager : WebControl
{
public event PagerEventHandler Navigate;
...
}
Теперь необходимо опять обратиться к теории. Нам необходимо, чтобы
наш элемент управления во первых умел генерировать постбеки, а во вторых
умел получать и обрабатывать информацию постбека. При этом также
необходимо, чтобы при постбеке передавалась информация о номере
страницы, клик на которую инициировал его. И такая возможность есть,
мало того реализовать ее в нашем элементе управления - дело 5 минут :).
Помните, в предыдущей статье при отрисовке тегов <a> я забивал
пустышкой тег href? Пришло время исправить это и добавить вызов
клентской функции, генерирующий постбек. Для этого можно воспользоваться
методами Page.GetPostBackEventReference или
Page.GetPostBackClientHyperlink (работа этих методов практически
идентична, разница лишь в том, что GetPostBackClientHyperlink добавляет
в начало возвращаемой строки строку "javascript:"). данные методы
принимают 2 параметра - указатель на элемент управления, генерирующий
постбек, и строка с дополнительной информацией. В нашем случае
значениями этих параметров будут ссылка this и номер страницы линка.
Соответственно теперь код, выводящий номер страницы, будет выглядеть
так:
output.AddAttribute(HtmlTextWriterAttribute.Href, Page.GetPostBackClientHyperlink(this, (pgIndex - 1).ToString()));
output.RenderBeginTag(HtmlTextWriterTag.A);
output.Write(pgIndex.ToString());
output.RenderEndTag();
Для получения же постбека тоже особой работы не нужно - необходимо
всего лишь реализовать интерфейс IPostBackEventHandler в нашем контроле
управления. Т.е. реализовать метод RaisePostBackEvent данного
интерфейса. Этот метод принимает один параметр - строку, содержащую
дополнительные данные, которые мы определяли при вызове метода
Page.GetPostBackClientHyperlink.Теперь же нам осталось только получить
эти данные (ведь именно в этом параметре находится номер выбранной
страницы) и вызвать событие.
Но для начала определим отдельный метод, проверяющий наличие
присоединенного обработчика события и вызывающий его если обработчик
есть. Этот метод обычно имеет префикс On перед именем события:
protected virtual void OnNavigate(PagerEventArgs e)
{
if (Navigate != null)
Navigate(this, e);
}
И только теперь реализуем метод RaisePostBackEvent
public void RaisePostBackEvent(string arg)
{
int cmd = Int32.Parse(arg);
PagerEventArgs e = new PagerEventArgs(cmd);
CurrentPage = cmd;
OnNavigate(e);
}
Все, на этом процесс реализации функциональности нашего пейджера
завершен. Полный код элемента управления вы можете скачать по ссылке в
конце статьи.
В данной статье я описал только малую часть вопросов, связанных с
разработкой собственных элементов управления и совсем ничего не сказал
про многие другие аспекты этой проблемы. Но назвать их и постараться
показать примерные пути их решения я могу :). Итак кроме генерации
событий, основанных на постбеке элемента управления существуют также
вопросы обработки данных при постбеке (интерфейс IPostbackDataHandler),
сохранение/восстановление состояния элементов управления при постбеке
(методы LoadViewState и SaveViewState), проблемы и решения реализации
большого количества событий в классе (класс EventHandlerList)
и шаблонные элементы управления. Отдельным большим куском создания
элементов управления идет и создание дизайнеров. Но все это темы для
отдельных статей, которые возможно я когда-то также соберусь написать
:). |