|
|
|
Уже множество разработчиков, перейдя на ASP.NET, смогли убедиться в том, что новая платформа для разработки Web-приложений от Microsoft является наиболее мощной и гибкой из всех имеющихся на рынке. Очень удобна прозрачное использование серверных элементов управления, но, хотя набор стандартных элементов велик - есть даже календарь, иногда хочется сделать что-то свое.
Причем, даже не "иногда". Потребность в написании своих элементов управления возникает (пусть часто и неосознанно) в написании любого мало-мальски крупного web-приложения. Пусть это даже будет обычная система новостей. Причем, должна быть отдельная страница со списком всех новостей и последние новости на главной странице. Причем все это должно быть продублировано для нескольких тем новостей.
Конечно, можно воспользоваться старым добрым Copy and Paste и сделать отдельный код на каждой странице, но представьте, что вы через некоторое время решили, например, изменить стиль списка новостей или, скажем, добавить поле "Автор". В этом случае придется менять код каждой копии.
В этом случае очень хочется чего-то вроде шаблона - параметризуемого куска HTML-кода, который (с соответствующими параметрами) можно было бы быстро вставить в любое место. Эта возможность реализуется в ASP.NET с помощью пользовательских элементов управления (user controls).
Пользовательский элемент управления как раз и является тем самым шаблоном, который можно вызывать в любом месте aspx- страницы. Его код тоже пишется на ASP.NET и хранится в .ascx - файле. Только его код не вставляется напрямую в код страницы, а создается html-код для элемента управления и уже он вставляется в html-код страницы при его генерации.
Для начала я предлагаю написать вместе простейший элемент управления. Для этого создайте новое web-приложение и в нем файл simple_control.ascx со следующим содержанием:
<%@ Control Language="c#"%>
<script language="C#" runat="server">
public string Name = "";
</script>
<h1>Hello, <%= Name %>!</h1>
|
Вот и готов наш первый элемент управления - довольно просто. Теперь давайте попробуем использовать его в какой-нибудь .aspx - странице
Создадим страницу control_test.aspx со следующим кодом:
<%@ Register Src=" simple_control.ascx" TagPrefix="Simple" TagName="Control" %>
<%@ Page language="c#" %>
<html>
<body>
<form id="ControlTest" method="post" runat="server">
<Simple:Control id="SimpleControl" runat="server" Name="John"/>
</form>
</body>
</html>
|
Открыв файл control_test.aspx в броузере, мы увидим следующее:
То есть, оно работает! Конечно, это простой пример, но и он может показать, насколько эффективными могут оказаться пользовательские элементы управления. Допустим, мы хотим "поздороваться" сразу с кучей людей и напишем для этого следующий код:
<%@ Register Src=" simple_control.ascx" TagPrefix="Simple" TagName="Control" %>
<%@ Page language="c#" %>
<html>
<body>
<form id="ControlTest" method="post" runat="server">
<Simple:Control runat="server" Name="John"/>
<Simple:Control runat="server" Name="Mary"/>
<Simple:Control runat="server" Name="Alice"/>
<Simple:Control runat="server" Name="Don"/>
<Simple:Control runat="server" Name="Michael"/>
<Simple:Control runat="server" Name="Afric"/>
</form>
</body>
</html>
|
Результатом нашего труда станет коллективное поздравление:
А теперь мы вдруг захотели слово "Hello" покрасить в зеленый цвет, а имена - в красный. Для этого нужно всего лишь поменять код у элемента на следующий:
<%@ Control Language="c#"%> <script language="C#" runat="server"> public string Name = ""; </script> <h1><font style="color:green;">Hello,</font> <font style="color:red;"><%= Name %>!</font></h1> |
Если бы мы явно писали код для каждого вызова элемента, нам пришлось бы изрядно потрудиться. Конечно, можно сказать, что такой вопрос решается стилями, но, во-первых, если бы это не было предусмотрено заранее, все равно пришлось бы прописывать стили в каждой строчке, а во-вторых, это, конечно, простой пример.
Файлы пользовательских элементов управления во многом похожи на файлы веб-форм. Но, конечно, есть отличия. В качестве основного декларативного тега используется тег @ Control. Все его параметры аналогичны параметрам тега @ Page, хотя многих параметров страницы он не имеет. Но мы опишем назначение наиболее часто используемых параметров тега @ Control:
| Параметр | Назначение |
|---|---|
| ClassName | Имя класса, которое будет использовано при создании элемента управления |
| Language | Язык, на котором написан весь inline-код страницы |
| Inherits | Указывает базовый класс для элемента управления. Эта техника используется Visual Studio.NET при работе с ASP.NET страницами и элементами управления. |
Далее может следовать любой ASP.NET код. Результат выполнения этого кода вставляется в текст получаемой в итоге страницы. Также могут использоваться специальные теги, такие как @ Inherits и скрипты (как клиентские, так и серверные).
Для использования пользовательского элемента в веб-форме, нужно сделать две вещи:
1) Зарагистрировать элемент.
Для этого есть специальный тег @ Register. Причем, есть два способа его использования - для регистрации сразу всех элементов, объявленных в некоторой сборке и индивидуальной регистрации. В первом случае синтаксис такой:
<% @ Register TagPrefix="префикс" Namespace="пространство_имен" Assembly="имя_сборки" %> |
Он регистрирует все элементы, объявленные в пространстве имен пространство_имен сборки имя_сборки и сопоставляет им префикс префикc (что это значит, будет объяснено позже)
Этот способ удобен, когда есть целая библиотека элементов управления и из нее используется множество элементов. В случае же, когда предпочтительнее индивидуальная регистрация, пользуются следующим синтаксисом:
<%@ Register TagPrefix="префикс" TagName="тег" Src="исходник" %> |
Эдесь тег сопоставляет элементу, описанному в файле исходник тег с именем тег и префиксом префикс.
Именно этот синтаксис был использован в нашем примере:
<%@ Register Src=" simple_control.ascx" TagPrefix="Simple" TagName="Control" %> |
2) Использовать элемент
Для обращения к элементу используется формат тега
<префикс:тег>, |
где префикс - это префикс, заданный в теге Register, а тег - это, в первом случае, имя класса, а во втором - заданное имя.
В нашей странице элемент был использован следующим образом:
<Simple:Control id="SimpleControl" runat="server" Name="John"/> |
Пользовательские элементы управления ничего особого не стоили бы, если не было бы возможности настраивать их вывод в зависимости от ситуации. В нашем примере мы для каждого экземпляра настраивали имя, которое выводил элемент.
Для того, чтобы задать свойство пользовательского элемента управления, нужно (в простейшем случае) объявить общедоступное (public) поле. Например, в нашем случае мы объявили поле Name:
<script language="C#" runat="server"> public string Name = ""; </script> |
Затем это поле можно использовать в коде элемента как обычную переменную:
<h1>Hello, <%= Name %>!</h1> |
Чтобы задать значение поля в странице, использующей элемент управления, их можно просто указать как атрибуты соответствующего тега:
<Simple:Control id="SimpleControl" runat="server" Name="John"/> |
При чем свойства могут быть самых различных типов - от строковых, до временнЫх. Рассмотрим расширенную версию нашего элемента:
<%@ Control Language="c#"%>
<script language="C#" runat="server">
public string Name = "";
public int Age = 0;
public DateTime BirthDate = DateTime.Today;
</script>
<h1><font style="color:green;">Hello,</font> <font style="color:red;"><%= Name %>!
<% if (Age != 0)
{ %>
(<%= Age %>)
<% } %>
<%= BirthDate %>
</font></h1>
|
и соответствующей страницы:
<%@ Register Src=" simple_control.ascx" TagPrefix="Simple" TagName="Control" %>
<%@ Page language="c#" %>
<html>
<body>
<form id="ControlTest" method="post" runat="server">
<Simple:Control runat="server" Name="John" Age="18" BirthDate="10.10.2003"/>
<Simple:Control runat="server" Name="Mary"/>
<Simple:Control runat="server" Name="Alice"/>
<Simple:Control runat="server" Name="Don"/>
<Simple:Control runat="server" Name="Michael"/>
<Simple:Control runat="server" Name="Afric"/>
</form>
</body>
</html>
|
Здесь видно, что мы используем строковые, числовые параметры и параметр типа DateTime. В результате все выглядит так:
Конечно, это простейший способ настройки страниц. Для большей гибкости используются свойства и методы. Использование свойств позволяет настраивать какое-то внутреннее поведение в зависимости от их значений или передавать их вложенным элементам управления. Рассмотрим такой элемент:
<%@ Control Language="c#"%>
<script language="C#" runat="server">
public string Text
{
get
{
return TextBox.Text;
}
set
{
TextBox.Text = value;
}
}
</script>
<asp:TextBox id="TextBox" runat="server" />
|
Используем этот элемент в нашей странице:
<%@ Register Src="simple_control.ascx" TagPrefix="Simple" TagName="Control" %>
<%@ Register Src="text_control.ascx" TagPrefix="Simple" TagName="Text" %>
<%@ Page language="c#" %>
<html>
<body>
<form id="ControlTest" method="post" runat="server">
<Simple:Control runat="server" Name="John" Age="18" BirthDate="10.10.2003"/>
<Simple:Control runat="server" Name="Mary"/>
<Simple:Control runat="server" Name="Alice"/>
<Simple:Control runat="server" Name="Don"/>
<Simple:Control runat="server" Name="Michael"/>
<Simple:Control runat="server" Name="Afric"/>
<Simple:Text runat="server" Text="Sample text"/>
</form>
</body>
</html>
|
В результате получим
Конечно, задавать свойства элементов можно также из кода страницы:
<%@ Register Src="simple_control.ascx" TagPrefix="Simple" TagName="Control" %>
<%@ Register Src="text_control.ascx" TagPrefix="Simple" TagName="Text" %>
<%@ Page language="c#" %>
<script language="C#" runat="server">
public void Button_Click( object sender, EventArgs e )
{
SimpleText.Text = "Text is changed";
}
</script>
<html>
<body>
<form id="ControlTest" method="post" runat="server">
<Simple:Control runat="server" Name="John" Age="18" BirthDate="10.10.2003"/>
<Simple:Control runat="server" Name="Mary"/>
<Simple:Control runat="server" Name="Alice"/>
<Simple:Control runat="server" Name="Don"/>
<Simple:Control runat="server" Name="Michael"/>
<Simple:Control runat="server" Name="Afric"/>
<br>
<Simple:Text id="SimpleText" runat="server" Text="Sample text"/>
<br>
<asp:Button Text="Change text" OnClick="Button_Click" runat="server"/>
</form>
</body>
</html>
|
В результате нажатия на кнопку меняется свойство нашего элемента управления:
Для работы с элементами управления также можно использовать методы. Для примера такого элемента возьмем миниатюрный напоминатель - элемент, выводящий список назначенных событий на данную дату.
Выглядит он так:
При выборе даты на календаре выводится список событий на этот день. Теперь давайте посмотрим его код.
Reminder.ascx:<%@ Control Language="c#" AutoEventWireup="false" Codebehind="Reminder.ascx.cs" Inherits="UserControlsDemo.Reminder" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%> <asp:Calendar id="Calendar" runat="server" Width="221px" Height="192px"></asp:Calendar> <asp:DataList id="lstEvents" runat="server"> <ItemTemplate> <b> <%# (Container.DataItem as RemindEvent).Text %> </b> </ItemTemplate> </asp:DataList> |
namespace UserControlsDemo
{
using System;
using System.Data;
using System.Drawing;
using System.Collections;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
/// <summary>
/// Пользовательский контрол, представляющий собой простой "напоминатель"
/// </summary>
public class Reminder : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.DataList lstEvents;
protected System.Web.UI.WebControls.Calendar Calendar;
private ArrayList _events;
public Reminder()
{
_events = new ArrayList();
}
/// <summary>
/// Добавляет новое событие
/// </summary>
/// <param name="e">Событие, которое должно быть добавлено</param>
public void Add( RemindEvent e )
{
_events.Add(e);
UpdateEvents();
}
/// <summary>
/// Удалает событие
/// </summary>
/// <param name="e">Событие, которое будет удалено</param>
public void Remove( RemindEvent e )
{
_events.Remove(e);
UpdateEvents();
}
/// <summary>
/// Очищает список событий
/// </summary>
public void Clear()
{
_events.Clear();
UpdateEvents();
}
private void Page_Load(object sender, System.EventArgs e)
{
UpdateEvents();
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Calendar.SelectionChanged += new System.EventHandler(this.Calendar_SelectionChanged);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void Calendar_SelectionChanged(object sender, System.EventArgs e)
{
UpdateEvents();
}
private void UpdateEvents()
{
ArrayList events = GetEventsByDate(Calendar.SelectedDate);
lstEvents.DataSource = events;
DataBind();
lstEvents.Visible = true;
}
/// <summary>
/// Представляет собой событие для напоминания
/// </summary>
public class RemindEvent
{
private DateTime _date;
private string _text;
/// <summary>
/// Дата, когда произойдет событие
/// </summary>
public DateTime Date
{
get
{
return _date;
}
set
{
_date = value;
}
}
/// <summary>
/// Описание события
/// </summary>
public string Text
{
get
{
return _text;
}
set
{
_text = value;
}
}
/// <summary>
/// Конструктор события
/// </summary>
/// <param name="date">Дата события</param>
/// <param name="text">Описание события</param>
public RemindEvent( DateTime date, string text )
{
_date = date;
_text = text;
}
}
private ArrayList GetEventsByDate( DateTime date )
{
ArrayList res = new ArrayList();
foreach (RemindEvent e in _events)
if (e.Date.Equals(date))
res.Add(e);
return res;
}
}
}
|
Как видно, здесь все просто. Хранится список всех событий, при смене даты идет поиск. И ко всему этому прикручен интерфейс из трех методов: Add, Remove и Clear.
Покажем как они используются:
ReminderTest.aspx:
<%@ Register Src="Reminder.ascx" TagPrefix="Demo" TagName="Reminder" %>
<%@ Page language="c#" Codebehind="ReminderTest.aspx.cs" AutoEventWireup="false" Inherits="UserControlsDemo.ReminderTest" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>ReminderTest</title>
<meta content="Microsoft Visual Studio 7.0" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="ReminderTest" method="post" runat="server">
<Demo:Reminder id="Reminder1" runat="server" /></form>
</form>
</body>
</HTML>
|
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace UserControlsDemo
{
/// <summary>
/// Summary description for ReminderTest.
/// </summary>
public class ReminderTest : System.Web.UI.Page
{
protected Reminder Reminder1;
private void Page_Load(object sender, System.EventArgs e)
{
Reminder1.Add(new Reminder.RemindEvent(DateTime.Today, "Super event"));
Reminder1.Add(new Reminder.RemindEvent(DateTime.Today, "Girlfriend birthday"));
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
}
|
Думаю, комментарии здесь излишни.
| << Предыдущая | Следующая >> |
| Контакт | Реклама на сайте | Спонсорам | Веб мастерам |
Лицензионное соглашение
- © 2000-2012 dotSITE
Хостинг .NET предоставлен
PARKING.RU
Поддержку сайта осуществляет Murano Software Inc., Offshore software development