Основы ASP.NET 2.0

       

Пользовательские элементы управления


Мы познакомились с большим количеством встроенных в ASP.NET элементов управления.

Хотя набор стандартных элементов велик — всегда может понадобиться такой элемент, которого в стандартной поставке нет. Или есть страница с такой функциональностью, которую хочется использовать и на других страницах. Можно, конечно воспользоваться клеем и ножницами (Copy-Paste), но сущность объектно-ориентированного и компонентного программирования — в повторном использовании кода, заключенного в готовые компоненты. Следовательно, нужно научиться создавать собственные элементы управления.

Пользовательские элементы управления инкапсулируют несколько готовых элементов в одном контейнере, который можно повторно использовать в проекте. Они наследуются от класса UserControl — наследника класса Control. Пользовательские элементы компилируются точно так же, как и страницы aspx.

Серверные элементы, кроме этого, реализуют собственное поведение и самостоятельно выводят HTML-код, который их отображает. Они могут наследоваться от WebControl или одного из классов стандартных элементов управления. Их можно использовать в любых проектах и распространять в виде откомпилированной PE (Portable Executable) сборки.

Мы знаем, что класс Page наследует класс Control, как и все элементы управления, некоторые прямо, а другие через класс WebControl или HtmlControl. Следовательно, между написанием страницы и разработкой собственного элемента управления должно быть много общего. У них тоже есть свой жизненный цикл. В классе Control определены события Init, Load, DataBinding, PreRender, Unload, Disposed.


Свойства, которые Control предоставляет своим наследникам, включают EnableViewState, ID, UniqueID, Page, Parent, SkinID, ViewState и Controls — коллекция дочерних элементов управления.

Класс Control предоставляет возможность помещать элемент управления в дерево элементов управления, которые отображаются на странице .aspx. Класс Control также реализует интерфейс System.ComponentModel. IComponent, который делает компонент конструктивным. Конструктивный компонент может быть добавлен в панель Toolboox визуального дизайнера, может быть помещен на разрабатываемую страницу методом drag-and-drop, может отображать свойства в окне свойств и обеспечивать другие виды поддержки режима разработки (в том числе Smart Tags).

Пользовательские элементы управления можно создавать в визуальном редакторе по той же модели, что и страницы aspx. Как всегда, откроем диалог NewFile и выберем тип страницы Web User Control. Расширение файла с дизайном элемента — ascx, а с кодом класса — ascx.cs. В отличие от страниц aspx, сам по себе пользовательский элемент нельзя увидеть в браузере, для этого он должен находиться на какой-нибудь странице:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %>

Как упоминалось в лекции 2, директива Control — это аналог директивы Page для элемента управления. На странице не указываются теги <html> и <body>, потому что содержание элемента включается в код страницы, в котором он содержится.



Изначально в элементе вообще нет никаких тегов.

Класс пользовательского элемента управления — наследник System.Web.UI.UserControl. В остальном он ничем не отличается от файла с классом страницы:

public partial class WebUserControl : System.Web.UI.UserControl { }

Можно добавить в него любые элементы управления и HTML-код:

<h1><%= Greeting %>, <%= Name %>!</h1> <asp:TextBox ID="txtName" runat="server"></asp:TextBox><br /> <asp:Button ID="btnClick" runat="server" Text="Button" />

В классе элемента управления определим его свойства:

string name; string greeting; public string Greeting { get { return greeting; }

set { greeting = value; } } public string Name { get { return name; }

set { name = value; } }

protected void Page_Init(object sender, EventArgs e) { btnClick.Text = "Enter your name and click"; }

При нажатии на кнопку свойства элемента заполняются данными из текстового поля:

protected void btnClick_Click(object sender, EventArgs e) { Name = txtName.Text; }

Теперь перетащите название элемента из Solution Explorer на любую страницу.

Чтобы использовать пользовательский элемент на странице, его надо зарегистрировать. Директива Register появляется автоматически:

<%@ Register Src=" WebUserControl.ascx" TagPrefix="User" TagName="GreetingControl" %>



Его значение может быть любым, кроме asp, которое зарезервировано для встроенных элементов управления ASP .NET. TagName — это имя элемента, идущее после префикса; атрибут Src определяет путь к файлу пользовательского элемента управления.

Теперь новый пользовательский элемент управления можно описать так:

<User:GreetingControl id="Hello" runat="server" Name="Heinrich" Greeting="Guten Tag"/>

Свойства, описанные в классе, можно устанавливать в описании на странице, причем они даже будут видны в окне свойств дизайнера.

Пользовательские элементы полностью участвуют в отображении страницы, и вставленные в него элементы ведут себя как обычно. Во время жизненного цикла страницы вызываются события встроенного в нее элемента управления.

В коде страницы можно манипулировать его свойствами:

protected void Page_Load(object sender, EventArgs e) { Hello.Greeting = "Привет"; }

Пользовательский элемент может получить доступ к странице, в которой находится, через свойство Parent. Если в родительскую форму добавить TextBox, он может прочитать его значение и использовать его:

<asp:TextBox ID="txtGreeting" runat="server"></asp:TextBox><br /> <User:GreetingControl id="Hello2" runat="server" Name="Heinrich" Greeting="Guten Tag" OnLoad="Hello2_Load"/>

protected void btnClick_Click(object sender, EventArgs e) { Name = txtName.Text; TextBox tb=Parent.FindControl("txtGreeting") as TextBox; if ( tb!= null) { Greeting = tb.Text; } }



Только что созданный элемент управления можно даже добавить в панель инструментов, и перетаскивать оттуда на любую страницу. Но директиву Register придется добавлять самим.

Можно попробовать создать WebUserControl в событии Page_Load, но это не даст результата. Причина в том, что класс объявлен лишь частично в файле отделенного кода, в нем не хватает функции отрисовки, которая появится при обработке страницы ascx ASP .NET.

Чтобы программно создать экземпляр пользовательского элемента управления, нужно вызвать функцию LoadControl, который вернет экземпляр класса System.Web.UI.Control, содержащий загружаемый элемент управления. Чтобы иметь доступ к свойствам класса WebUserControl, нужно преобразование типа. И, как и всякий другой элемент управления, загруженный пользовательский элемент управления может быть добавлен в коллекцию элементов управления web-формы. Его нельзя добавить в страницу, так как его составной частью является кнопка, которая может находиться только в форме:

WebUserControl wuc = (WebUserControl)Page.LoadControl("WebUserControl.ascx"); wuc.Greeting = "Здоровеньки булы"; wuc.Name = "Тарас"; form1.Controls.AddAt(0, wuc);

Более полезный пользовательский элемент управления — нижний колонтитул любой страницы. Его можно поместить на шаблон дизайна. Он может отобразить юридическую информацию, адрес web-мастера и дату последнего обновления:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Footerl.ascx.cs" Inherits="Footerl" %> Copyright &copy; <asp:Label ID="lblYear" runat="server" /> by Your Company Name.<br />

Замечания, комментарии, проблемы? Свяжитесь с web-мастером <asp:Label ID="lblEmail" runat="server" /><br /> Дата последней модификации этой страницы: <asp:Label ID="lblLastMod" runat="server" /><br />

Текст в элементах Label меняется в обработчике Page_Load.

protected void Page_Load(object sender, EventArgs e) { lblYear.Text = DateTime.Now.Year.ToString(); lblEmail.Text = "<a href='mailto:webmaster@" + Request.Url.Host.Replace("www.", "") + "'>webmaster</a>"; lblLastMod.Text = System.IO.File.GetLastWriteTime(Server.MapPath(Request.Url.LocalPa th)).ToLongDateString(); }


Содержание раздела