386 MGraphics.ru - ASP.NET - Написание пользовательских элементов управления под ASP.NET
Уроки photoshopa


ASP.NET

Написание пользовательских элементов управления под ASP.NET

Условия перепечатки материалов

Рейтинг статьи: 11111
Проголосовало 636 человек.
Оцените статью:

Написание пользовательских элементов управления под ASP.NET

Введение

Уже множество разработчиков, перейдя на 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 и скрипты (как клиентские, так и серверные).

Использование пользовательских элементов управления в ASP.NET страницах

Для использования пользовательского элемента в веб-форме, нужно сделать две вещи:

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>
Reminder.ascx.cs:
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>
ReminderTest.aspx.cs:
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
    }
}

Думаю, комментарии здесь излишни.

Copyright by © 2000-2004 dotSITE
Автор:
Автор:

Разместил: Vulko
Опубликовано: 03.07.2004
Статья "ASP.NET - Написание пользовательских элементов управления под ASP.NET" прочтена 36149 раз.





Последние новости