Создание пользовательских контролов в Web приложениях ASP.NET на C#

Создание пользовательских контролов в Web приложениях ASP.NET на C#

Создание пользовательских контролов имеет целью обеспечение возможности повторного использования ранее созданных блоков программного кода, имеющих законченное функциональное предназначение, в других приложениях. Это реализовано в Visual Studio Net через предоставление возможности создания пользовательских контролов (элементов управления), которые, по своему принципу использования, полностью аналогичны стандартным контролам, входящим в набор контролов, отображаемых в Toolbox.

Для создания собственного элемента управления можно воспользоваться одним из двух подходов:

  • Разработать проект решения, выполняющий требуемые функции, и, далее, преобразовать его в контрол.

  • Непосредственно создать контрол, используя Visual Studio Net.

Вначале рассмотрим второй из перечисленных способов. Пусть задачей нашего контрола будет отображения рисунка, сохраненного в файле на сервере и вызываемого при нажатии кнопки или выборе ссылки в приложении.


В начало

Создание контролов с использованием шаблона проекта Web Control Library


В начало

Создание контрола

Для создания контрола создадим проект решения MyWCShowImage (вначале, как и обычно, используя IIS, создаем виртуальный каталог с именем MyWCShowImage, для некоторого реального каталога MyWCShowImage, находящегося в директории С:\SamplesASP и, далее, создаем Web Control Library проект решения (см. раздел "Создание Web приложений в С#") - Рис.1.

MyWCShowImage001.gif

Рис.1 Создание Web Control Library проекта решения

Рассмотрим код MyWCShowImage.css, сформированный Visual Studio Net:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace MyWCShowImage
{
 [DefaultProperty("Text"),
  ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]
 public class WebCustomControl1 : System.Web.UI.WebControls.WebControl
 {
  private string text;
  [Bindable(true),Category("Appearance"),DefaultValue("")]
  public string Text
  {
   get
   {
    return text;
   }
   set
   {
    text = value;
   }
  }
  protected override void Render(HtmlTextWriter output)
  {
   output.Write(Text);
  }
 }
}

Итак:

Наш класс создаваемого контрола наследует класс WebControl, являющийся, в свою очередь, наследником класса Control. Заметим, что все элементы управления ASP.NET, за исключением четырех (Literal, PlaceHolder, Repeater, и Xml - прямые потомки System.Web.UI.Control) используют одно из двух пространств имен - System.Web.UI.HtmlControls и System.Web.UI.WebControls, и, эти классы также являются наследниками класса System.Web.UI.Control (HtmlControls используются для формирования традиционных элементов HTML, а WebControls для формирование серверных элементов управления). Например, при помещении на форму контрола Label со вкладки Tools мы имеем его включение в код странички как:

protected System.Web.UI.WebControls.Label Label1; 

Класс Control, наследником которого является WebControls, представляет базовую функциональность для элемента управления (размещение в коллекции серверных элементов управления Web формы и их отрисовку). Также он предоставляет функциональность для добавления в панель элементов управления и включении в форму. Создаваемый контрол является наследник этих классов, что и определяет идентичность его использовании со стандартными серверными элементами управления, о чем речь пойдет ниже.

В коде мы видим метод Render(), который обеспечивает генерацию Html кода при его отображении на web-страничке. Пока это вывод на страничку строковой переменной. Класс HtmlTextWriter представляет множество методов для генерации правильного html кода (формирование закрывающихся и открывающихся тэгов, добавление стилей, атрибутов, параметров и т.п.). Кроме того, при использовании для формирования кода HtmlTextWriter можно не заботиться о версии браузера - класс сформирует правильный код, различный для различных браузеров.

Среди свойств класса мы видим пока только одно public свойство - Text, доступное как для чтения, так и для записи.

Изменим имя контрола и имя, отображаемое при помещении контрола на форму проекта решения (можно также переименовать в Solutation Explorer и имя файла WebCustomControl1, но это ни на что не влияет):


[DefaultProperty("Text"),
 ToolboxData("<{0}:MyImageShow runat=server><\{0}:MyImageShow>")]

public class MyImageShow : System.Web.UI.WebControls.WebControl
{
 ....

С этого момента мы имеем имя контрола MyImageShow, а при его помещении на страничку в дизайнере проекта решения он будет иметь имя MyImageShow1.

Если откомпилировать проект на данном этапе, (выставив тип проекта Release в меню Build\Configuration Manager) - меню Build\Build Solutation, то в директории C:\SamplesASP\MyWCShowImage\bin\Release\, будет создана dll - MyWCShowImage.dll. Это и есть созданный контрол, который можно использовать в любых Web проектах.


В начало

Добавление контрола в Toolbox

Для использования dll скопируем ее в директорию, где располагаются все dll (уточнить можно, выбрав в контекстном меню Toolbox пункт Add\Remove Items, на вкладке .NET Frameworks нажимаем кнопку Browse) - для Visual Studio .NET 2003 это C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\.

Далее создадим проект решения Pr1 (как обычно, используя IIS, создаем виртуальный каталог с именем Pr1, для некоторого реального каталога Pr1, находящегося в директории С:\SamplesASP и создаем ASP NET WEB Application проект решения - см. раздел "Создание Web приложений в С#").

Поместим созданный компонент в ToolBox. Выбирем в контекстном меню Toolbox пункт Add\Remove Items, нажимаем кнопку Browse и находим созданную dll (Рис.2).

MyWCShowImage002.gif

Рис.2 Добавление контрола в Toolbox

После нажатия кнопки Open dll становится выбранной. После нажатия Ok компонент с именем MyImageShow появляется на вкладке Toolbox (Рис.3).

MyWCShowImage003.gif

Рис.3 Добавление контрола в Toolbox


В начало

Использование контрола в Web проекте

С этого момента мы можем использовать наш компонент, как и любой другой серверный элемент управления (контрол). Поместим его обычным образом на форму (Рис.4). Перейдем в режим редактирования HTML-кода и убедимся, что на странице HTML добавлена директива @ Register для этого элемента управления и что префикс тега директивы равен cc1.

<%@ Register TagPrefix="cc1" Namespace="MyWCShowImage" Assembly="MyWCShowImage" %>

MyWCShowImage004.gif

Рис.4 Добавление контрола в проект решения

Теперь достаточно записать код, представленный ниже, чтобы некоторый текст был отображен на форме (Рис.5).

private void Page_Load(object sender, System.EventArgs e)
{
 MyImageShow1.Text="My Теxt";
}

MyWCShowImage005.gif

Рис.5 Использование созданного контрола


В начало

Изменение внешнего вида контрола и его параметров

В Solutation Explorer решения контрола для узла MyWCShowImage, в его контекстном меню выбираем Add\Add New Item\Bitmap File. Изменим в диалоговом окне имя на MyImageShow.bmp (имя файла значка должно точно совпадать с именем класса ) и нажимаем кнопку Open. В Solutation Explorer появится узел MyImageShow.bmp. В меню Images\Grid Settings ставим галочки напротив Pixel, Grid и Tile Grid. Устанавливаем размер картинки 16*16pix (удобнее перетаскиванием рамки). Размеры можно теперь установить и в контекстном меню узла MyImageShow.bmp - пункт Properties. Рисуем картиночку (по своему усмотрению), после чего закрываем редактор, подтвердив запрос на сохранение внесенных изменений.

В окне Properties Build Action устанавливаем Embeded Resource(Действие при построении - Внедренный ресурс).

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

Для того, чтобы легче в HTML коде было выделить пользовательские элементы, можно изменить префикс тега. Для этого откроем файл AssemblyInfo и добавим строки строку:

using System.Web.UI;
[assembly: TagPrefix("CustomLabel", "myc")]

Перекомпилируем проект решения. Теперь вместо "ссс" при помещении этого контрола на странице Web Forms его HTML-тег будет содержать "myc".


В начало

Добавление функциональности контролу

Мы поставили задачей использование контрола для отображения рисунков из файлов. Изменим код следующим образом (выделено жирным шрифтом):

namespace MyWCShowImage
{
 [DefaultProperty("Text"),
  ToolboxData("<{0}:MyImageShow runat=server>")]
  public class MyImageShow : System.Web.UI.WebControls.WebControl
  {
   private string text;
[Bindable(true),
Category("Appearance"),DefaultValue("")]
  public string Text
  {
   get
   {
    //Код в одну строку

   string s=string.Format("<div
          align=center><img
           src=\"http://localhost/Images/{0}.gif\"
            ALT=\"{0}.gif\"></div>",text);
      return s;

   }
   set
   {
    text = value;
   }
  }
  protected override void Render(HtmlTextWriter output)
  {
   output.Write(Text);
  }
 }
}

Откомпилируем проект. Используя IIS, создаем виртуальный каталог с именем Images, для некоторого реального каталога Images, находящегося в директории С:\SamplesASP.

В проекте Pr1 удалим (контекстное меню Tools, Add\Remove Items) ранее добавленный компонент MyImazgeShow. Кроме того, в Reference в Solutation Explorer проекта удалим узел MyImageShow. Скопируем MyWCShowImage.dll, как описано выше, в директорию C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\, и вновь добавляем контрол в проект.

Чтобы каждый раз не добавлять и не удалять контролы - можно просто закрыть и вновь открыть Visual Studio.

Добавим в проект два контрола Button и наш контрол, который будет выглядеть в проекте так, как показано на Рис.6.

MyWCShowImage006.gif

Рис.6 Проект решения

Добавим в проект решения следующий код:

private void Page_Load(object sender, System.EventArgs e)
{
 MyImageShow1.Text="a";
}
private void Button1_Click(object sender, System.EventArgs e)
{
 MyImageShow1.Text="a";
}
private void Button2_Click(object sender, System.EventArgs e)
{
 MyImageShow1.Text="a1";
}

Если теперь, в директорию C:\SamplesASP\Images скопировать какие либо рисунки с именами "a.gif" и "a1.gif", то, откомпилировав проект и, вызвав из браузера http://localhost/Pr1/, мы можем, нажимая кнопки 1 и 2, последовательно отображать один или другой рисунок (Рис.7).

MyWCShowImage007.gif

Рис.7 Отображение рисунков в браузере

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


В начало

Следующий и, пожалуй, наиболее простой метод создания компонентов состоит в следующем: формируется страница с необходимой функциональностью и элементами управления, а затем выполняется ее преобразование в пользовательский контрол.


В начало

Создание контрола

Как и ранее, задачей контрола будет отображение рисунков, хранимых в файлах сервера (в принципе, рисунки могут храниться и в базе данных с любым способом хранения). Для схожести с первым разделом, будем отображать рисунки "a.gif" и "a1.gif" из директории C:\SamplesASP\Images, для которой создан виртуальный каталог Images(см. выше).

Для создания контрола cоздадим проект решения MyWCShowImage2 (вначале, как и обычно, используя IIS, cоздаем виртуальный каталог с именем MyWCShowImage2, для некоторого реального каталога MyWCShowImage2, находящегося в директории С:\SamplesASP и, дадее, создаем ASP.NET Web Application проект решения (см. раздел "Создание Web приложений в С#").

Параметр Location при создании проекта будет:

http://localhost/MyWCShowImage2

Переименуем файл WebForm1.aspx в MyShowImage2.aspx (контекстное меню узла WebForm1 в Solutation Explorer, пункт Rename - автоматически должны изменить названия и файлы узла с расширениями ".cs" и ".resx" проекта). Переименуем класс WebForm1 в MyShowImage2. Добавим на форму контрол HyperLink и откомпилируем проект.

Далее выполняем ряд изменений в проекте:

  • 1. Удалим со страницы тэги HTML и FORM вместе с их содержимым. В тэге BODY оставим один тэг. Html файл будет иметь всего две строчки:

    <%@ Page language="c#" Codebehind="MyShowImage2.aspx.cs" 
                 AutoEventWireup="false" 
                            Inherits="MyWCShowImage2.MyShowImage2" %>
    <asp:HyperLink id="HyperLink1" style="Z-INDEX: 101;" 
                 runat="server" Width="150px">
                    HyperLink</asp:HyperLink>
    
  • 2. Заменим директиву @ Page директивой @ Control.

    <%@ Control language="c#" ....
    
  • 3. Изменяем ссылку на расширение файла в атрибуте Codebehind директивы Control с ".aspx" на ".ascx" (предполагается последующие изменение расширения имени файла п.4).

  • 4. Переименовываем файл MyShowImage2.aspx в MyShowImage2.ascx (в контекстном меню узла MyShowImage2.aspx пункт Rename), одновременно будет переименован файл с расширениями ".cs" (MyShowImage2.aspx.cs).

  • 5. В файле MyShowImage2.ascx изменим класс родителя System.Web.UI.Page на System.Web.UI.UserControl.

    Файл будет выглядеть следующим образом:

    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 MyWCShowImage2
    {
     public class MyShowImage2 : System.Web.UI.Page
     {
      protected System.Web.UI.WebControls.HyperLink HyperLink1;
      private void Page_Load(object sender, System.EventArgs e)
      {
      }
      override protected void OnInit(EventArgs e)
      {
       InitializeComponent();
       base.OnInit(e);
      }
      private void InitializeComponent()
      {    
       this.Load += new System.EventHandler(this.Page_Load);
      }
     }
    }
    
  • 6. Устанавливаем Build, Configuration Manager, Releas. Компилируем проект.

Элемент управления будет сформирован как MyWCShowImage2.dll файл в директории bin проекта.


В начало

Возможное использование контрола в Web проектах

Данный контрол можно использовать как пользовательский контрол в пределах одного проекта и как контрол, который может быть внедрен в другие проекты. Однако, в зависимости от цели, способы использования и оформления кода проекта могут отличаться.

Рассмотрим различные способы внедрения контрола в проекты.


В начало

Использование контрола в пределах проекта решения, в котором он создан

Итак, в некоторой директории MyWCShowImage2 (для нее уже создана и виртуальная директория) у нас создан контрол, который физически представляет собой два файла - MyWCShowImage2.dll и MyShowImage2.ascx, которые нам далее необходимы. Так как мы собираемся использовать контрол в данном проекте, то можно основную форму, в которой он будет использоваться, добавить к проекту.

В меню Проект (или контекстном меню узла MyWCShowImage2 в Solutation Explorer) выберем Add\Add Web Form. В диалоговом окне выбираем Templates\Web Form. Изменим имя формы на ShowImage.aspx и нажимаем Open. В окно дизайнера формы дважды перетащим узел MyShowImage2.ascx, который отобразится на форме как два контрола. (Рис.8).

MyWCShowImage008.gif

Рис.8 Использование контролов в текущем проекте решения

В Solutation Explorer выберем в контекстном меню узла ShowImage пункт Set As Start Page (для выбора страницы, можно и переименовать узел в Default.aspx, если были заданы соответствующие свойства при создании виртуальной директории).

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

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

Под функциональностью в данном случае мы будем понимать основное предназначение контрола (отображение рисунков). Для этого нам надо знать хотя бы имя рисунка и иметь возможность его извлечения из HTML кода контрола, помещенного на форму.

Для страницы ShowImage.aspx переходим в режим View HTML и в теге form добавим параметр с именем рисунка.

<form id="Form1" method="post" runat="server">
 <uc1:MyShowImage2 id="MyShowImage21" 
    runat="server" imagename="a.gif"></uc1:MyShowImage2>
 <uc1:MyShowImage2 id="MyShowImage22" 
  runat="server" imagename="a1.gif"></uc1:MyShowImage2>
</form>

Для того, чтобы контрол выполнял функцию извлечения имени рисунка и формирования ссылки на соответствующий рисунок, дополним файл ShowImage.aspx следующим кодом:

public class MyShowImage2 : System.Web.UI.UserControl 
{
 protectedHyperLink HyperLink1;
 private     string nameimage=string.Empty;
 private void Page_Load(object sender, System.EventArgs e)
 {
  //Извлекаем имя рисунка
  if(imagename == string.Empty) return;
  HyperLink1.Text="Рисунок "+nameimage;
  HyperLink1.NavigateUrl="http://localhost/Images/"+nameimage;
  HyperLink1.ForeColor=Color.Blue;
 }
 //Добавляем свойство imagename, которое введено в HTML коде
 public string imagename
 {
  get 
  {
   return nameimage;
  }
  set 
  {
   nameimage = value;
  }
 }
..........

Откомпилируем проект (Rebuild Solutation), и выполним вызов, результат которого показан на Рис.9

http://localhost/MyWCShowImage2/ShowImage.aspx

MyWCShowImage009.gif

Рис.9 Использование контрола в пределах одного проекта


В начало

Внедрение контрола в другие проекты

Вернемся к созданному выше проекту решения Pr1 (Рис.6). Именно в этот проект мы и внедрим созданный выше контрол. И, к отображению картинок по нажатию кнопок (Рис.7), мы добавим отображение картинок по нажатию ссылки HyperLink. Забегая немного вперед, мы будем стремиться получить результат, показанный на Рис.10., где слева расположена ссылка Рисунок, а справа - результат выбора по этой ссылки.

MyWCShowImage010.gif

Рис.10 Использование контролов в других проектах

Для того, чтобы иметь возможность использовать контрол не задумываясь о его месте нахождения - cкопируем MyWCShowImage2.dll, как описано выше, в директорию C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\. Добавим, как мы уже делали, ссылку через контекстное меню Solutation Explorer для узла Reference на нашу MyWCShowImage2.dll. Скопируем в директорию C:\SamplesASP\Pr1 файл MyShowImage2.ascx.

Выполним в меню Project пункт Show All Files (если мы не видим в Solutation Explorer файла MyShowImage2.ascx). Теперь дважды перетащим файл на форму (Рис.11).

MyWCShowImage011.gif

Рис.11 Добавление контрола к проекту решения

Прежде чем компилировать и выполнить выбор странички проекта, обратим внимание на код Html файла Default.aspx, а именно на строчки из файла, приводимые ниже:

<%@ Register TagPrefix="cc1" Namespace="MyWCShowImage" 
                               Assembly="MyWCShowImage" %>
<%@ Register TagPrefix="uc1" TagName="MyShowImage2" 
                               Src="MyShowImage2.ascx" %>

Из этих двух строчек мы видим разницу в регистрации стандартного контрола, добавляемого в ToolBox(MyWCShowImage) и пользовательского (MyWCShowImage2). Эти же строчки показывают и то, как можно добавить отображения для контролов, внедряемых в ToolBox, без использования метода Render.

Следующие две строчки показывают как контрол может быть добавлен в Web форму, а именно - не в виде HyperLink, а контрола, для которого можно указывать и параметры.

<%uc1:MyShowImage2 id="MyShowImage21" 
  imagename="a.gif" runat="server"></uc1:MyShowImage2>
<br>
<uc1:MyShowImage2 id="MyShowImage22" 
  imagename="a1.gif" runat="server"></uc1:MyShowImage2>

Теперь мы можем откомпилировать проект и выполнить вызов

http://localhost/Pr1,

результат которого показан на Рис.9.


В начало

Пример динамического создания элементов контрола

До сих пор мы использовали (например, HyperLink ) контрол, в предположении, что он имеет элементы отображения на странице ASPX или их код формируется как полный код HTML. Однако есть возможность и динамически создать элемент отображения контрола.

Здесь приведен код, который не требует разъяснения, так как мы уже использовали практически все методы и свойства класса UserControl. Для создания данного контрола использован шаблон проекта Web Control Library (см. первый раздел статьи). В силу этого контрол внедряется в ToolBox. Динамическое создание HyperLink дает возможность не описывать его Html отображение.

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Text;
namespace MyWCShowImage3
{
 [DefaultProperty("Text"), 
 ToolboxData("<{0}:MyShowImage3 runat=server>")]
 public class MyShowImage3 : System.Web.UI.WebControls.WebControl
 {
  protected HyperLink HyperLink1;
  private StringBuilder MySBuilder;
  private     string nameimage=string.Empty;
  //извлекаем imagename
  public string Text
  {
   get 
   {
    return nameimage;
   }
   set 
   {
    nameimage = value;
   }
  }
  protected override void 
  Render(System.Web.UI.HtmlTextWriter writer)
  {
   if(nameimage == string.Empty) return;
   MySBuilder=new StringBuilder();
   HyperLink1=new HyperLink();
   HyperLink1.Text="Рисунок "+nameimage;
   HyperLink1.NavigateUrl="http://localhost/Images/"+nameimage;
   HyperLink1.ForeColor=Color.Blue;
   //Добавляем контрол в список контролов
   this.Controls.Add(HyperLink1);
   MySBuilder.Append(GetRenderedChildren());
   writer.Write(MySBuilder.ToString());
  }
  //Запись контрола
  private string GetRenderedChildren()
  {
   StringBuilder sb=new StringBuilder();
   System.IO.StringWriter stwr = new System.IO.StringWriter(sb);
   System.Web.UI.HtmlTextWriter htw = 
   new System.Web.UI.HtmlTextWriter(stwr);
   this.RenderChildren(htw);
   return sb.ToString();
  }
 }
}

С данным контролом можно делать все, что указано в параграфе "Изменение внешнего вида контрола и его параметров", а после добавления в ToolBox, можно добавлять на форму как любой стандартный контрол (Рис.12).

MyWCShowImage012.gif

Рис.12 Добавление контрола к проекту решения

Единственное, что требуется для функционирования контрола после помещения его на форму - добавить в свойство Text имя файла рисунка.

<cc2:MyShowImage3 id="MyShowImage32" 
 Text="a1.gif" runat="server"></cc2:MyShowImage3>
<br>
<br>
<cc2:MyShowImage3 id="MyShowImage31" 
 Text="a.gif" runat="server"></cc2:MyShowImage3>


В начало

Об использовании шаблона Web User Control

Шаблон Web User Control обеспечивает создание контрола аналогичного тому, как мы это рассмотрели в разделе "Преобразование страницы Web Forms в пользовательский элемент управления" в параграфе "Создание контрола". Использование контрола полностью аналогично рассмотренному в параграфе "Возможное использования контрола в Web проектах". Таким образом, использование данного шаблона всего лишь облегчает нам создание пользовательского контрола.

Для того, чтобы убедиться в вышесказанном, можно сравнить код, полученный нами при преобразование Web формы в контрол (см. код, полученный путем преобразовния), с кодом, сгенерированном по шаблону:

public class WebUserControl1 : System.Web.UI.UserControl
{
 private void Page_Load(object sender, System.EventArgs e)
 {
 }
 override protected void OnInit(EventArgs e)
 {
  InitializeComponent();
  base.OnInit(e);
 }		
 private void InitializeComponent()
 {
  this.Load += new System.EventHandler(this.Page_Load);
 }
}

Молчанов Владислав 30.11.2005г.

Еcли Вы пришли с поискового сервера - посетите мою главную страничку

На главной странице Вы найдете программы комплекса Veles - для тех кто готовится к экзаменам на право управления автомобилем или мотоциклом, программу NumberPhoto, созданную для работы с фото, сделанными цифровым фотоаппаратом, программу Bricks - игрушку для детей и взрослых, программу записную книжку, теоретический материал по программированию в среде Borland C++ builder, C# (C .Net).

В начало страницы

В начало темы

На главную страницу сайта


Сайт управляется системой uCoz