Создание собственных элементов управления ASP.NET AJAX

Спектр элементов управления, предлагаемых пакетом ASP.NET AJAX Control Toolkit, продолжает расширяться от версии к версии.

Более того, помимо этого впечатляющего списка он содержит еще одну инфраструктуру, которая предназначена для создания своих собственных элементов управления. Если вы постоянно используете одни и те же эффекты, реализованные на JavaScript, вполне оправданным будет сделать их доступными через ASP.NET AJAX.

В этом разделе будет создан расширитель, который ограничивает возможность ввода в текстовое поле предопределенным набором символов – данная функциональная возможность не поддерживается средствами HTML. В пакете ASP.NET AJAX Control Toolkit имеется шаблон проекта для Visual Studio 2005, облегчающий эту работу. Сначала вам нужно будет установить шаблон, затем изменить его и добавить логику работы нового расширителя.

Как вы уже знаете, пакет ASP.NET AJAX Control Toolkit поставляется в виде одного файла DLL, который содержит полный комплект элементов управления. Для создания собственного компонента вам потребуется скомпилировать программный код. К счастью, для упрощения процесса создания расширителей, таких как тот, что мы собираемся написать, в состав пакета входит шаблон для Visual Studio.

В главе 10 вы познакомились с мастером установки VSI, который кроме всего прочего создает шаблоны для разработки веб?сайтов, управляемых компонентами из ASP.NET AJAX Control Toolkit.


Это «все прочее» в основном является шаблонами на C# и VB, позволяющими создавать свои собственные элементы управления. Когда вы запустите среду разработки Visual Studio и приступите к созданию нового проекта, обратите внимание на шаблон ASP.NET AJAX Control Project.

Предполагается, что создаваемый расширитель должен расширять возможности существующего серверного элемента управления ASP.NET. Поэтому в Visual Studio откройте веб?сайт, где вы сможете одновременно работать со своим расширителем и с существующим элементом управления ASP.NET. Загрузите веб?сайт ASP.NET AJAX в Visual Studio. В меню File (файл) выберите пункт Add (добавить) и затем пункт New Project (новый проект). Выберите шаблон ASP.NET AJAX Control Project. Используйте в примере имя проекта TextBoxMask.

Новый шаблон создает проект по умолчанию, используя имя проекта (расширитель TextBoxMask). Изначально он состоит из четырех файлов:
TextBoxMaskBehavior.js
Программный код JavaScript, составляющий основу расширителя
TextBoxMaskDesigner.cs
Программный код, используемый конструктором Visual Studio
TextBoxMaskExtender.cs
Программный код C#, который работает с инспектором свойств
Visual Studio в режиме проектирования и позволяет с его помощью изменять свойства элемента управления

Основная работа будет вестись внутри самой важной части расширителя – в файле TextBoxMaskBehavior.js, где будет сосредоточена вся JavaScript?логика работы на стороне клиента.

Но сначала необходимо разобраться с двумя другими файлами примера.


Откройте файл TextBoxMaskDesigner.cs и обратите внимание: содержимое этого файла – не что иное, как заготовка класса. Она выглядит, как показано в примере 13.1.
Пример 13.1. Класс TextBoxMaskDesigner
TextBoxMaskDesigner.cs
using System.Web.UI.WebControls;
using System.Web.UI;
namespace TextBoxMask
{
class TextBoxMaskDesigner : AjaxControlToolkit.Design.
ExtenderControlBaseDesigner
{
}
}

Файл TextBoxMaskExtender.cs содержит информацию о расширителе для конструктора. Как видно из примера 13.2, в программном коде имеется ссылка на файл TextBoxMaskBehavior.js. По умолчанию для элементов, используемых совместно с этим расширителем, выбран тип данных Control. Однако мы предполагаем расширять текстовое поле, поэтому измените тип Control на TextBox.
[TargetControlType(typeof(TextBox))]

Далее в файле вы можете увидеть единственное свойство, присутствующее в шаблоне: MyProperty. Удалите этот член класса и создайте строковое свойство ValidChars с соответствующими методами доступа. Позднее в этом свойстве будут храниться символы, допустимые для ввода в текстовое поле.

В качестве методов доступа к значению свойства будут использоваться функции GetPropertyValue() и SetPropertyValue().


Кроме того, установите атрибут DefaultProperty, чтобы сделать ValidChars свойством расширителя по умолчанию. Полный программный код представлен в примере 13.2.
Пример 13.2. Класс TextBoxMaskExtender
TextBoxMaskProperties.cs
using System;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.ComponentModel;
using System.ComponentModel.Design;
using AjaxControlToolkit;
[assembly: System.Web.UI.WebResource("TextBoxMask.TextBoxMaskBehavior.js",
"text/javascript")]
namespace TextBoxMask
{
[Designer(typeof(TextBoxMaskDesigner))]
[ClientScriptResource("TextBoxMask.TextBoxMaskBehavior",
"TextBoxMask.TextBoxMaskBehavior.js")]
[TargetControlType(typeof(TextBox))]
[DefaultProperty("ValidChars")]
public class TextBoxMaskExtender : ExtenderControlBase
{
// TODO: Добавьте сюда свои методы доступа к свойствам.
//
[ExtenderControlProperty]
[DefaultValue("")]
public string ValidChars
{
get
{
return GetPropertyValue("ValidChars", "");
}
set
{
SetPropertyValue("ValidChars", value);
}
}
}
}

Единственное свойство, доступное по умолчанию и не требующее регистрации, – это TargetControlID, ссылающееся на элемент управления, с которым будет связан расширитель. Наконец, нам необходимо создать программный код JavaScript, который будет расширять функциональные возможности текстовых полей ввода, с которым связан элемент управления. Этот код будет находиться в файле TextBoxMaskBehavior.js.

Файл шаблона .js содержит несколько полезных комментариев, описывающих действия, которые следует выполнить в соответствующих местах программы. В первую очередь необходимо определить переменные для каждого свойства расширителя. В соответствии с синтаксическими соглашениями имена переменных должны начинаться с символа подчеркивания (_), за которым следует символ в нижнем регистре:
this._validChars = "";

После этого необходимо написать методы доступа ко всем свойствам, которые должны быть доступны из программного кода JavaScript. Это довольно простая задача, которую практически полностью можно выполнить с помощью операций копирования и вставки. Следует учитывать, что язык JavaScript чувствителен к регистру символов, поэтому вы должны быть последовательны при выборе регистра как для имен переменных JavaScript, так и для свойств C#.
get_ValidChars : function( ) {
return this._validChars;
},
set_ValidChars : function(value) {
this._validChars = value;
}

Последний этап заключается в создании программного кода инициализации расширителя. Это то место, где код JavaScript присоединяется к рассматриваемому элементу управления. Мы создаем пример расширителя, который проверяет символы, вводимые пользователем в текстовом поле. Работать он будет следующим образом: расширитель определяет свойство, которое позволяет разработчику указать строку, содержащую допустимые для ввода символы. Например, если свойству будет присвоена строка "0123456789", текстовое поле сможет принимать только цифровые символы.

В нашем примере мы хотим, чтобы функция проверки вызывалась по нажатию клавиши. Если пользователь нажимает клавишу, не соответствующую ни одному допустимому символу, событие должно быть отменено, чтобы этот символ не появился в текстовом поле. Обработчик события должен быть помещен в метод initialize() класса TextBoxMaskBehavior (шаблоны класса и метода уже были созданы).

Мы предоставим платформе ASP.NET AJAX выполнение проверки возможностей броузера по определению и обработке нажатий клавиш пользователем. Большую часть этой работы возьмет на себя метод $addHandler(). Сначала нужно вставить его в метод initialize(). Порядок подключения метода к событию выглядит следующим образом:
this._keydownHandler = Function.createDelegate(this, this._onkeydown);
$addHandler(this.get_element( ),"keydown", this._keydownHandler);

Используя метод dispose(), вы можете этот обработчик удалить, на этот раз с помощью метода removeHandler(), как показано ниже:
$removeHandler(this.get_element( ), "keydown", this._keydownHandler);
this._keydownHandler = null;

Наконец, необходимо написать программный код JavaScript расширителя. Сначала, проанализировав тип броузера, этот код должен определить, какая клавиша была нажата. Затем код должен отыскать введенный символ в списке допустимых символов. Если искомый символ отсутствует в этом списке, метод завершается инструкцией return false, что приводит к отмене события и предотвращает появление символа в текстовом поле. Если искомый символ обнаружен в списке, метод завершается инструкцией return true и событие передается дальше.

В Internet Explorer возврат значения false из обработчика события не может использоваться для предотвращения появления введенного символа в текстовом поле. Для этого в обработчике события нажатия клавиши необходимо вызвать метод preventDefault().
this._onkeydown : function(e) {
var key = e.rawEvent.keyCode;
if (key >= 96 && key <= 105) {
key ?= 48;
}
if (key == 8 || key == 9 || key == 16
|| (key >= 35 && key <= 40) || key == 45 || key == 46
|| _validChars.indexOf(String.fromCharCode(key)) != ?1) {
return true;
} else {
e.preventDefault( );
return false;
};
}

И это все, что имеет отношение к JavaScript. Полный программный код расширителя приводится в примере 13.3. Все комментарии, имевшиеся в шаблоне элемента управления, остались нетронутыми; к ним можно обратиться как к справочной информации.

Пример 13.3. Реализация расширителя на JavaScript
TextBoxMaskBehavior.js
// README
//
// Добавление свойства выполняется в два этапа:
//
// 1. Создать переменную?член, в которой будет храниться значение свойства.
// 2. Добавить методы доступа к свойству get_ и set_.
//
// Не забывайте, что имена переменных и методов
// чувствительны к регистру символов!
//
Type.registerNamespace('TextBoxMask');
TextBoxMask.TextBoxMaskBehavior = function(element) {
TextBoxMask.TextBoxMaskBehavior.initializeBase(this, [element]);
// TODO : (Этап 1) Добавьте сюда переменные ваших свойств
//
this._validChars = null;
}

TextBoxMask.TextBoxMaskBehavior.prototype = {
initialize : function( ) {
TextBoxMask.TextBoxMaskBehavior.callBaseMethod(this, 'initialize');
// TODO: добавьте сюда код инициализации
this._keydownHandler = Function.createDelegate(this, this._onkeydown);
$addHandler(this.get_element( ), "keydown", this._keydownHandler);
},
dispose : function( ) {
// TODO: добавьте сюда код, освобождающий ресурсы
$removeHandler(this.get_element( ), "keydown", this._keydownHandler);
this._keydownHandler = null;
TextBoxMask.TextBoxMaskBehavior.callBaseMethod(this, 'dispose');
},
_onkeydown : function(e) {
var key = e.rawEvent.keyCode;
if (key >= 96 && key <= 105) {
key ?= 48;
}
if (key == 8 || key == 9 || key == 16
|| (key >= 35 && key <= 40) || key == 45 || key == 46
|| this._validChars.indexOf(String.fromCharCode(key)) != ?1) {
return true;
} else {
e.preventDefault( );
return false;
}
},
// TODO: (Этап 2) Добавьте здесь методы доступа к свойствам
//
get_ValidChars : function( ) {
return this._validChars;
},
set_ValidChars : function(value) {
this._validChars = value;
}
}
TextBoxMask.TextBoxMaskBehavior.registerClass(
'TextBoxMask.TextBoxMaskBehavior',
AjaxControlToolkit.BehaviorBase);

Теперь давайте соберем проект. В результате будет создан файл TextBoxMask.dll, куда будет включен файл .js в виде внедренного ресурса, доступного для элемента управления ScriptManager на этапе исполнения. Обычно расширитель TextBoxMask появляется в палитре компонентов автоматически. Но добавлять его в проект веб?сайта придется вручную. Для этого в окне Solution Explorer (обозреватель решений) щелкните правой кнопкой мыши на веб?сайте ASP.NET AJAX и выберите пункт контекстного меню Add Reference (добавить ссылку). Во вкладке Projects (проекты) загрузите сборку TextBoxMask.dll. После этого сборка автоматически будет скопирована в каталог Bin. Ссылка на файл .dll добавлена в веб?проект. Всякий раз, когда вы будете перекомпилировать свой элемент управления в Visual C# или Visual Basic, вам необходимо будет обновлять ссылку в Visual Web Developer. Для этого в окне Solution Explorer (обозреватель решений) откройте папку Bin, правой кнопкой мыши щелкните на TextBoxMask.dll и выберите пункт контекстного меню Update Reference (обновить ссылку).

Если у вас открыта страница, где используется этот элемент управления, вам может потребоваться закрыть и затем опять открыть ее. В проекте веб-сайта создайте новую страницу ASP.NET. Зарегистрируйте префикс тега расширителя в самом начале страницы, добавив следующую разметку:
<%@ Register Assembly="TextBoxMask" Namespace="TextBoxMask" TagPrefix="cc1"%>

Затем добавьте в страницу элемент управления TextBoxMask – не забудьте добавить элемент управления ScriptManager. Добавьте текстовое поле, а затем свяжите расширитель с текстовым полем установкой свойства расширителя – TargetControlID. Программный код, приведенный в примере 13.4, создает текстовое поле, которое допускает ввод исключительно цифровых символов, перечисленных в свойстве ValidChars.

Реализовать такое поведение только силами JavaScript было бы несколько сложнее, поэтому расширитель TextBoxMask действительно поможет вам сэкономить время и силы. И как дополнительное преимущество – получившийся расширитель может использоваться многократно.

Пример 13.4. Использование собственного расширителя TextBoxMask.aspx
<%@ Page Language="C#" %>
<%@ Register Assembly="TextBoxMask" Namespace="TextBoxMask" TagPrefix="cc1"%>
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> ASP.NET AJAX

(body)
(asp:ScriptManager ID="ScriptManager1" runat="server" /)
TargetControlID="TextBox1" ValidChars="1234567890" />

(asp:TextBox ID="TextBox1" runat="server")(/asp:TextBox)


(/body)


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

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела ASP.NET AJAX на эту тему:
Содействие проекту Control Toolkit