Опубликован: 07.05.2010 | Доступ: свободный | Студентов: 1678 / 62 | Оценка: 4.56 / 4.06 | Длительность: 34:11:00
Лекция 6:

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

Доступ из кода Web-страницы к составным компонентам пользовательского элемента управления

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

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

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

Первый способ

В пользовательский элемент вводят промежуточные свойства или методы доступа, через которые из Web-страницы обращаются к его компонентам. Это напоминает прием, который применяется в C++ для поддержания инкапсуляции (закрытости) данных: переменные-члены класса с модификатором доступа private упаковывают в функции доступа public, которые сами видят эти переменные, а их, в свою очередь, видят клиенты этого класса.

Пусть, например, пользовательский элемент управления MyControl1 как объект порождается классом MyControl и в качестве одного из компонентов содержит в себе объект Label1 библиотечного класса System.Web.UI.WebControls.Label. Класс Label наследует от базового класса System.Web.UI.WebControls.WebControl свойство BackColor, которое, в свою очередь, имеет тип System.Drawing.Color. Напрямую из Web-страницы нельзя установить новое значение свойства BackColor компонента Label1 пользовательского элемента. Но можно раскрыть это свойство для Web-страницы, введя промежуточное свойство BackColor (или с другим именем) в классе самого пользовательского элемента. Сказанное схематично изображено на рисунке


Выполним это на практике.

  • Создайте заготовку пользовательского элемента Web User Control с именем MyControl.ascx с раздельным кодом (флажок Place code in separate file мастера включен)
  • Перейдите в режим Design редактора заготовки и поместите на нее из вкладки Standard элемент Label с именем Label1
  • В панели Solution Explorer откройте файл поддержки MyControl.ascx.cs, удалите из класса MyControl заготовку обработчика Page_Load() за ненадобностью и дополните класс свойствами доступа, чтобы он стал таким
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 MyControl : System.Web.UI.UserControl
{
    public string Text
    {
        get { return Label1.Text; }
        set { Label1.Text = value; }
    }
	
    public System.Drawing.Color BackColor
    {
        get { return Label1.BackColor; }
        set { Label1.BackColor = value; }
    }
	
    public System.Drawing.Color ForeColor
    {
        get { return Label1.ForeColor; }
        set { Label1.ForeColor = value; }
    }
}

Здесь мы использовали имена посреднических свойств родителя MyControl1 точно такие, как у прямых свойств компонента Label1. Но это не обязательно. Можно использовать любые имена. Просто, когда Иванов, Петров, Сидоров означают одно и то же лицо, но в разных инстанция числятся по разному, это " хужее ".

  • Создайте пользовательскую тестовую страницу с раздельным кодом под именем MyControlTest.aspx и переведите ее в режим редактирования Design
  • Из панели Solution Explorer из дерева файлов приложения перенесите на тестовую страницу узел MyControl.ascx. Убедитесь, что экземпляр пользовательского элемента управления зарегистрировался на тестовой странице под именем MyControl1
  • Попробуйте выделить элемент управления и убедитесь, что он не выделяется и добавленные нами свойства не видны в панели Properties. Это значит, что декларативно (в режиме проектирования) из страницы настраивать его нелься, но можно программно управлять (в режиме выполнения) через введенные нами общедоступные свойства, в чем мы и хотим убедиться.
  • Поместите на страницу под пользовательским элементом управления компонент RadioButtonList из вкладки Standard и убедитесь, что он имеет ID="RadioButtonList1"
  • Через коллекцию Items элемента RadioButtonList1 задайте три радиокнопки с такими свойствами
    • Text="Красный"; Value="Red"
    • Text="Зеленый"; Value="Green"
    • Text="Синий"; Value="Blue"
  • Установите свойство RepeatDirection элемента RadioButtonList1 в значение Horozontal
  • Выделите компонент RadioButtonList1 и через панель Properties создайте обработчик для его события SelectedIndexChanged
  • Под списком радиокнопок поместите компонент Input (Submit) из вкладки HTML

Дескрипторное представление страницы будет иметь вид

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeFile="MyControlTest.aspx.cs" 
    Inherits="MyControlTest" %>
	
<%@ Register Src="MyControl.ascx" TagName="MyControl" TagPrefix="uc1" %>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <uc1:MyControl ID="MyControl1" runat="server" />
        <br />
        <br />
        <asp:RadioButtonList ID="RadioButtonList1" runat="server" 
             RepeatDirection="Horizontal" 
             OnSelectedIndexChanged="RadioButtonList1_SelectedIndexChanged">
            <asp:ListItem Value="Red">Красный</asp:ListItem>
            <asp:ListItem Value="Green">Зеленый</asp:ListItem>
            <asp:ListItem Value="Blue">Синий</asp:ListItem>
        </asp:RadioButtonList></div>
        <br />
        <input id="Submit1" type="submit" value="submit" />
    </form>
</body>
</html>

Мы хотим, чтобы на клиенте при щелчке на кнопке Submit выполнялась обратная отсылка на сервер, где бы код страницы через введенные нами в класс пользовательского элемента управления дополнительные свойства менял настройку элемента Label1. Этот код смены настройки нужно поместить в созданный нами обработчик радиокнопок, чтобы он срабатывал каждый раз, когда получит обратную отсылку с требованием пользователя выполнить новые настройки. В результате элемент Label1 сгенерирует нужный HTML-код и отошлет его клиенту.

  • Заполните обработчик RadioButtonList1_SelectedIndexChanged() страницы в файле MyControlTest.aspx.cs следующим кодом
    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 MyControlTest : System.Web.UI.Page
    {
        protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e)
        {
            int index = RadioButtonList1.SelectedIndex;
    	
            switch (index)
            {
                case 0:
                    MyControl1.ForeColor = System.Drawing.Color.White;
                    MyControl1.BackColor = System.Drawing.Color.Red;
                    break;
                case 1:
                    MyControl1.ForeColor = System.Drawing.Color.Aqua;
                    MyControl1.BackColor = System.Drawing.Color.Green;
                    break;
                case 2:
                    MyControl1.ForeColor = System.Drawing.Color.Yellow;
                    MyControl1.BackColor = System.Drawing.Color.Blue;
                    break;
            }
    	
            if(index != -1)
                MyControl1.Text = RadioButtonList1.Items[index].Value;
        }
    }
  • Откомпилируйте страницу и проверьте ее работоспособность. При щелчке на кнопке код страницы меняет свойства компонента Label1, хотя он входит в состав пользовательского элемента управления MyControl1. Взаимодействие страницы с Label1 происходит через добавленные нами в пользовательский элемент управления дополнительные глобальные свойства.