|
|
|||||||||||||||||||||||||||||
|
Программное создание шаблонов серверных элементов управления (исходники)Источник: Gotdotnet Майк Попп (Mike Pope), Никил Котари (Nikhil Kotha)
АннотацияДемонстрируется, как программно создавать шаблоны для серверных ASP.NET-элементов управления Repeater, DataList и DataGrid; даны примеры на Visual Basic .NET и Visual C# .NET. СодержаниеСтатья поделена на разделы, в каждом из которых демонстрируются все более сложные способы создания шаблонов (templates). Например, из первого раздела вы узнаете, как создавать в коде простейшие наблоны. В последующих разделах этот шаблон усложняется, к нему добавляется новая функциональность. К концу статьи вы научитесь создавать полнофункциональный шаблон, способный к связыванию с данными (data binding).
ТребованияЭта статья предполагает, что вы знаете, как создавать страницы на основе Web-форм (Web Forms) и серверных элементов управления ASP.NET. Кроме того, предполагается, что вы хотя бы экспериментировали в Web Forms Designer с созданием шаблонов для ASP.NET-элементов Repeater или DataList. Базовую информацию о шаблонах см. по ссылке Web Server Controls Templates. Наконец, предполагается, что вы умеете связывать элементы управления на страницах - Web-формах с данными. Базовую информацию о связывании с данными см. в документации Microsoft® Visual Studio® .NET (Web Forms Data Binding). ВведениеСерверные элементы управления ASP.NET Repeater, DataList и DataGrid рассчитаны на связывание с данными (data binding). Они генерируют один элемент (item) (например, строку) для каждого элемента (element) в связанном с ними источнике данных. Разметка данных определяется шаблонами. Шаблон - это контейнер для других элементов управления, не имеющий собственного пользовательского интерфейса (UI). Чтобы выводить информацию, к шаблону нужно добавить элементы управления и настроить их свойства, определяющие внешний вид (display properties) (обычно через связывание с данными). Во время своей работы элемент управления перебирает элементы в источнике данных и для каждого из них создает свой элемент, соединяющий элементы управления в шаблоне с информацией в элементе данных. Элементы управления Repeater и DataList позволяют выводить результат в более свободной форме: элементами могут быть строки таблицы, пункты маркированного списка, элементы списка, разделенные запятыми, или что угодно еще. Элемент управления DataGrid использует предопределенный формат - сетку (grid). Каждый элемент данных соответствует строке в сетке. При отображении элемента управления каждый элемент показывается как строка таблицы. Определение шаблоновЕсли вы работаете с элементами управления Repeater, DataList или DataGrid на странице Web Forms, создать шаблон на этапе разработки несложно. DataList поддерживает окно редактирования в стиле WYSIWYG. Что касается Repeater, его шаблоны создаются в окне просмотра HTML (HTML view) в виде специальных элементов, вложенных в элемент управления. Для создания нового шаблонного столбца в элементе управления DataGrid воспользуйтесь окном Properties. Но это предполагает, что шаблоны создаются на этапе разработки. По разным причинам иногда на этом этапе не известно, какие шаблоны понадобятся или какой в них нужен текст и элементы управления. В этом случае надо создавать шаблоны "на лету". А для этого следует понять основные принципы создания классов и связывания с данными в Web Forms. В этом вам и поможет данная статья. Примечание. Кроме того, можно создавать шаблоны в виде пользовательских элементов управления Web Forms и динамически связывать их с элементами управления на странице. Более подробную информацию см. в Creating a Templated User Control в документации .NET Framework SDK. Базовые сведения о программном создании шаблоновДля начала рассмотрим, как создать простейший шаблон в коде. Для этого нужно выполнить следующие выражения:
Как видите, здесь создается экземпляр класса MyTemplate. Откуда берется этот класс шаблона? Вы сами его и создаете. Примечание. Шаблоны для DataGrid создаются в коде чуть иначе, так как в этом случае вы создаете столбец. Дополнительные сведения вы найдете в конце статьи. Однако большинство сведений о элементах управления DataList и Repeater относятся и к DataGrid. Базовый класс шаблонаКласс шаблона относительно прост. Как минимум, в нем нужно:
Конечно, смысл шаблона - в выводе текста и элементов управления для каждого элемента в источнике данных. Это делается в методе класса InstantiateIn, именно там создается UI шаблона. Обычно сценарий работы с этим методом таков: вы создаете новый элемент управления, настраиваете необходимые свойства, а затем добавляете его в набор (cillection) Controls родительского элемента. Статический текст напрямую добавить в этот набор нельзя, но вы можете создать элементы управления Literal или LiteralControl, настроить их свойства Text и добавить их к родительскому набору. Метод InstantiateIn передает ссылку на родительский элемент управления (элемент управления Repeater, DataList или DataGrid), что упрощает последний шаг. Ниже приведен полный класс шаблона, выводящего статический текст ("Item number:") и счетчик. Счетчик хранится в разделяемой или статической (в зависимости от языка программирования) переменной класса itemcount и увеличивается на 1 при каждом создании нового элемента.
Тестирование класса шаблонаЧтобы посмотреть, как работает наш класс, протестируйте его с элементом управления Repeater. Начните с создания новой страницы на основе Web Forms и выполните следующие действия.
Теперь вы готовы к созданию класса шаблона. Выполните следующие действия.
Добавление шаблонов других типовВышеприведенные примеры демонстрируют работу с единственным шаблоном, а именно: с шаблоном элемента (item template). Из этого раздела вы узнаете, как создавать более сложную версию класса шаблона, позволяющую указывать шаблон заголовка (header template), шаблон нижнего колонтитула (footer template), шаблон переменного элемента (alternating item template) (для Repeater и DataList) и т. д. Во-первых, можно создать отдельный класс шаблона для каждого типа шаблона или базовый класс шаблона и производные от него классы для различных типов шаблонов. Это может оказаться практичным, если шаблоны очень сложны или сильно отличаются друг от друга. С другой стороны, можно воспользоваться одним классом для всех элементов и указывать, каков тип создаваемого шаблона. Для этого классу следует передать соответствующее значение. На самом деле, подойдут значения из перечисления ListItemType, уже определенного для типов шаблонов в элементах управления Repeater, DataList и DataGrid. Приведенный ниже пример - усовершенствованная версия предыдущего кода. Теперь класс содержит явный конструктор, который принимает строку, определяющую тип шаблона. Для выяснения типа создаваемого шаблона в методе InstantiateIn применяется оператор Select Case или switch в зависимости от языка программирования. Чтобы показать преимущества создания шаблонов различного типа, в примере создается таблица с разным цветом фона для шаблона переменного элемента (alternating item template).
Для создания разных шаблонов используется примерно такой код:
Добавление в шаблон поддержки связывания с даннымиСейчас наш класс шаблона способен выводить только статические данные. В этом разделе мы дополним его поддержкой включения данных из источника. Обращаться к данным из класса шаблона можно по-разному, в зависимости от способа создания класса. По-хорошему архитектура страницы сама должна реализовать связывание с данными. Добавляя элементы управления к шаблону, вы добавляете и обработчик события DataBinding. Оно вызывается после того, как шаблон создаст все свои элементы управления. Примечание. Возможно, вы полагаете, что выражение связывания с данными можно встроить просто в виде строки при создании элементов управления в шаблоне - точно так же, как и при определении шаблонов на этапе разработки. Но ничего не выйдет: оказывается, выражения связывания с данными превращаются в код при обработке страницы, т. е. до создания шаблона. В обработчике события DataBinding вы можете управлять содержимым элемента управления. Обычно (но не обязательно) данные откуда-то загружаются и записываются в свойство Text элемента управления. Примечание. Базовую информацию о связывании данных на страницах Web Forms см. в документации Visual Studio .NET по ссылке Web Forms Data Binding. Связывание обработчика событий с элементами управленияНачните со связывания обработчика событий с создаваемыми в шаблоне элементами управления. В приведенном ниже фрагменте элемент управления в шаблоне связывается с обработчиком TemplateControl_DataBinding. (Код самого обработчика вы добавите позже.)
Примечание. Дополнительную информацию о динамическом добавлении обработчиков событий см. AddHandler and RemoveHandler (для Visual Basic) и Events Tutorial (для Visual C#) в документации Visual Studio .NET. Обратите внимание, что в этом примере текст, добавляемый к строковому свойству Text элемента управления, отличается от текста в предыдущем. Он содержит только начало строки таблицы и ячейки для шаблона элемента. Ячейку и строку мы закончим в обработчике события связывания с данными. Создание обработчика событияТеперь нам нужен обработчик, вызываемый при связывании элемента управления с данными. Обработчик является частью класса шаблона и ничем не отличается от других методов класса (вроде InstantiateIn). Сигнатура обработчика показана в следующем примере. Имя обработчика должно совпадать с именем, указанном при связывании с обработчиком.
При вызове метода вы передаете в аргументе sender ссылку на элемент управления, поэтому можете настраивать его свойства. Так как этот аргумент имеет тип object, его надо привести к элементу управления правильного типа (в нашем примере - к Literal). Как получить доступ к данным? Для каждого элемента в источнике данных Repeater, DataList или DataGrid создает один элемент, содержимое которого основывается на шаблоне. Каждый такой элемент содержит свойство DataItem, обеспечивающее доступ к данным для этого элемента (т. е. к соответствующей строке данных). Однако при вызове обработчика события связывания с данными вы имеете дело с конкретным элементом управления, а не с шаблонным элементом. Поэтому вам придется пройти по иерархическому дереву вверх от элемента управления к элементу шаблона. Лучше всего для этого подходит свойство элемента управления NamingContainer, возвращающее ссылку на элемент шаблона, в котором создан этот элемент управления. (Кроме того, ссылку на контейнер хранит свойство Parent. Однако, если элемент управления вложен в другой - например, в Panel или Table, - это свойство не вернет ссылку на элемент шаблона.) Таким образом, чтобы связать элемент управления в шаблоне с конкретными данными, необходимо предпринять следующие действия.
Следующий код демонстрирует один из способов выполнения требуемых действий (за основу взяты ранее приведенные примеры). Это полный обработчик события связывания с данными для элементов управления Literal, созданных для шаблонов. Код создает переменную container типа RepeaterItem (так как мы работаем с элементом управления Repeater) и присваивает ее свойству NamingContainer связываемого элемента управления. Теперь по этой ссылке можно обратиться к DataItem контейнера-объекта. Это легко сделать, вызвав метод Eval объекта DataBinder (этот же метод часто применяется в выражениях связывания с данными) и передав ему ссылку на объект DataItem контейнера и имя требуемого поля. Если в ваших шаблонах содержатся элементы управления множества типов, создайте обработчик события связывания с данными для каждого типа элемента управления.
Программное создание шаблонов в элементе управления DataGridВышеописанная процедура работает для элементов управления Repeater и DataList. Кроме того, можно программно создавать шаблоны для элемента управления DataGrid. Процесс создания собственно шаблона ничем не отличается. Но есть различия в его использовании:
Коротко: в элементе управления DataGrid разрешены следующие типы столбцов:
Наверное, вы уже догадались, что именно для столбцов последнего типа программно создаются шаблоны. Другими словами, если вы хотите изменять элементы управления в столбце DataGrid на этапе выполнения, вам следует использовать шаблонные столбцы и создавать шаблоны "на лету". В следующем примере показано, как создать два шаблона для элемента управления DataGrid и назначить их столбцам. Вначале создаются шаблоны, практически так же, как и в предыдущих примерах. Однако есть два небольших отличия. Во-первых, конструктор класса шаблона принимает два параметра; во втором параметре передается имя создаваемого столбца. Во-вторых, в этот пример включен код, создающий шаблон EditItem, который создает элемент управления Textbox.
В следующем примере демонстрируется создание шаблонов столбцов и назначение их столбцам.
ЗаключениеХотя примеры в этой статье достаточно просты, они демонстрируют все основные принципы создания шаблонов в коде. Конечно, шаблоны, которые вы создадите в своих приложениях, скорее всего окажутся гораздо более сложными - все шаблоны в этой статье легко можно создать на этапе разработки. Но теперь вы знаете достаточно, чтобы создавать шаблоны "на лету".
|
|