|
В прошлой статье я попытался рассказать, как нужно
рисовать собственные 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)
и шаблонные элементы управления. Отдельным большим куском создания
элементов управления идет и создание дизайнеров. Но все это темы для отдельных
статей, которые возможно я когда-то также соберусь написать
:).
|