Пользовательские элементы управления
Ниже мы убедимся, что программно загруженные в портальные каркасы пользовательские элементы управления обрабатывают свои события точно также, как будто бы каждый из них находится на отдельной исполнимой странице.
- Откройте на редактирование файл DynamicUserControls.aspx.cs и добавьте в класс DynamicUserControls следующий код
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class DynamicUserControls : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { // Загружаем портальные каркасы MyLoadControls(Panel1); MyLoadControls(Panel2); MyLoadControls(Panel3); } // Вспомогательная функция private void MyLoadControls(Control containerPanel) { // Объявляем вспомогательные ссылки на интерфейсные // элементы текущего контейнера DropDownList list = null; PlaceHolder ph = null; Label lbl = null; // Перебираем все дочерние элементы текущего // контейнера и ищем ссылки на объекты дочерних // интерфейсных элементов по их типам foreach (Control ctrl in containerPanel.Controls) { if (ctrl is DropDownList) list = (DropDownList)ctrl; else if (ctrl is PlaceHolder) ph = (PlaceHolder)ctrl; else if (ctrl is Label) lbl = (Label)ctrl; } // Берем информацию из выделенного // элемента списка текущего контейнера string lstValue = list.SelectedItem.Value; string lstText = list.SelectedItem.Text; lbl.Text = ""; // Заполняем текущий контейнер. // Проверяем наличие нужного расширения if (lstValue.EndsWith(".ascx")) { ph.Controls.Add(Page.LoadControl(lstValue)); lbl.Text = "Загрузили: " + lstValue + " - " + lstText; } } }Листинг 32.28. Код файла DynamicUserControls.aspx.cs
Пользовательский элемент управления иногда проще сделать из обычной страницы .aspx, выполнив следующие шаги:
- Сначала нужно разработать обычную страницу aspx, отладить ее и проверить в действии
- Переименовать расширение файла из aspx в ascx
- Директиву @Page вместе с ее атрибутами следует удалить и заменить директивой @Control с требуемыми атрибутами
- Удалить из кода все дескрипторы <html>, <body>, <form>, <head>
- В коде застраничного файла заменить базовый класс Page на UserControl
- Если мы используем модель совмещенного кода и файл имеет исполнимый код в блоке скриптов, то нужно в директиву Control обязательно добавить атрибут ClassName =" имя_файла_или_любое_имя ". Он извещает ASP.NET, что код, который нужно компилировать, находится в том же файле в дескрипторах <script>. Без этой информации файл компилироваться не будет
Используя перечисленные шаги, создадим пользовательские элементы управления, которые реализуют пользовательский интерфейс и функциональность, использованную нами при выполнении предыдущих упражнений в тестовых страницах. Из этих тестовых страниц мы их и переделаем. Получится так, что пользовательский элемент управления будет включен в тестовую страницу, а сама тестовая страница будет превращена в пользовательский элемент и будет динамически включаться по выбору из списка на исполнимую страницу DynamicUserControls.aspx в зарезервированные PlaceHolder -места.
-
В панели Solution Explore выделите при нажатой клавише Ctrl следующие файлы
- HeaderTest.aspx
- TimeDisplayTest.aspx
- LinkTableTest.aspx
- MyControlTest.aspx
- Выполните команду Copy затем Paste (на верхнем узле проекта) контекстного меню
-
Присвойте
копиям те же самые имена, только с расширением .ascx
- HeaderTest.ascx
- TimeDisplayTest.ascx
- LinkTableTest.ascx
- MyControlTest.ascx
- Откройте новые файлы в дескрипторном режиме и замените директиву @Page на @Control, все остальные атрибуты бывшей директивы @Page оставьте прежними. Теперь это будут не страницы, а пользовательские элементы управления. Директиву @Register с ее атрибутами изменять не нужно
- Удалить из кода все дескрипторы <html>, <body>, <form>, <head> и закрывающие их дескрипторы
В результате новые пользовательские элементы должны иметь следующий код интерфейсной части
HeaderTest.ascx |
---|
<%@ Control AutoEventWireup="true" CodeFile="HeaderTest.ascx.cs" Inherits="HeaderTest" Language="C#" %> <%@ Register TagPrefix="myElem" TagName="Header" Src="Header.ascx" %> <myElem:Header ID="Header1" runat="server" /> |
TimeDisplayTest.ascx |
<%@ Control Language="C#" %> <%@ Register Src="TimeDisplay.ascx" TagName="TimeDisplay" TagPrefix="uc1" %> <uc1:TimeDisplay ID="TimeDisplay1" runat="server" Format="" /> <br /> <br /> <hr /> <br /> <uc1:TimeDisplay ID="TimeDisplay2" runat="server" Format="Сегодня dddd, dd MMMM yyyy<br />Текущее время HH:mm:ss" /> |
LinkTableTest.ascx |
<%@ Control AutoEventWireup="true" CodeFile="LinkTableTest.ascx.cs" Inherits="LinkTableTest" Language="C#" %> <%@ Register Src="LinkTable.ascx" TagName="LinkTable" TagPrefix="uc1" %> <uc1:LinkTable ID="LinkTable1" runat="server" OnLinkClicked="LinkTable1_LinkClicked" /> <br /> <asp:Label ID="lblInfo" runat="server"></asp:Label> |
MyControlTest.ascx |
<%@ Control AutoEventWireup="true" CodeFile="MyControlTest.ascx.cs" Inherits="MyControlTest" Language="C#" %> <%@ Register Src="MyControl.ascx" TagName="MyControl" TagPrefix="uc1" %> <uc1:MyControl ID="MyControl1" runat="server" /> <br /> <br /> <asp:RadioButtonList ID="RadioButtonList1" runat="server" OnSelectedIndexChanged="RadioButtonList1_SelectedIndexChanged" RepeatDirection="Horizontal"> <asp:ListItem Value="Red">Красный</asp:ListItem> <asp:ListItem Value="Green">Зеленый</asp:ListItem> <asp:ListItem Value="Blue">Синий</asp:ListItem> </asp:RadioButtonList> <br /> <input id="Submit1" type="submit" value="submit" /> |
- Для новых файлов *.ascx откройте файлы скрытого кода *.ascx.cs и замените в объявлении класса имя базового класса с " System.Web.UI.Page " на " System.Web.UI. UserControl "
Остальной код классов останется прежним. Мы закончили выполнение упражнения. Код исполнимой страницы DynamicUserControls.aspx при очередной загрузке будет программно создавать свои пользовательские элементы управления для каждого контейнера Panel и размещать их в элементах PlaceHolder.
- Выполните страницу DynamicUserControls.aspx и испытайте ее работу
Результат будет примерно таким