private Button cycleButton = new Button();
Чтобы сконфигурировать композитный элемент управления, необходимо сделать так, чтобы всякий элемент управления-потомок добавлялся к коллекции Controls
и правильно инициализировался. Мы делаем это, переопределяя метод CreateChildControls()
и помещая туда необходимый код:
protected override void CreateChildControls() {
cycleButton.Text = 'Cycle colors.';
cycleButton.Click += new System.EventHandler(cycleButton_Click);
Controls.Add(cycleButton);
Controls.Add(rainbowLabel);
}
Здесь мы используем только метод Add()
коллекции Controls
, чтобы работа была корректной. Добавляем также обработчик событий для кнопки, чтобы мы могли циклически менять цвета, это достигается точно таким же образом, как и для других событий. Обработчик событий уже знаком:
protected void cycleButton_Click(object sender, System.EventArgs e) {
rainbowLabel.cycle();
}
Данный вызов заставляет цвета метки циклически изменяться.
Чтобы предоставить пользователям композитного элемента управления доступ к тексту в потомке rainbowLabel
, можно добавить свойство, которое отображается в свойство Text
потомка:
public string Text {
get {
return rainbowLabel.Text;
}
set {
rainbowLabel.Text = value;
}
}
Осталось только реализовать Render()
. По умолчанию, если не переопределить этот метод, вызывается метод Render()
каждого элемента управления потомка. Однако, чтобы получить дополнительный контроль над этим, можно самим вызывать эти методы или, лучше, открытые экземпляры методов RenderControl()
:
protected override void Render(HtmlTextWriter writer) {
rainbowLabel.RenderControl(writer);
cycleButton.RenderControl(writer);
}
Здесь не выводится никакой код HTML, хотя можно было легко это сделать. Нам нужно просто передать полученный экземпляр HtmlTextWriter
в метод RenderControl()
для потомка, чтобы обычным образом был вставлен HTML, созданный этим потомком. Можно использовать такой элемент управления почти так же, как и RainbowLabel
:
<form method='post' runat='server' ID='Form1'>
<PCS:RainbowLabel2 Runat='server'
Text='Multicolored label composite' ID='rainbowLabel2' />
</form>
вместе со связанным объявлением в скрытом коде формы.
Элемент управления выборочным опросом
Теперь воспользуемся изложенной техникой и создадим более сложный специальный элемент управления. Конечный результат позволит с помощью следующего кода ASP.NET:
<form method='post' runat='server' ID='Form1'>
<PCS: StrawPoll Runat='server' ID='strawPoll1'
PollStyle='voteonly' Title='Who is your favorite James Bond?'>
<PCS:Option Name='SeanConnery' Votes='101' />
<PCS:Option Name='Roger Moore' Votes='83' />
<PCS:Option Name='George Lazenby' Votes='32' />
<PCS:Option Name='Timothy Dalton' Votes='28' />
<PCS:Option Name='Pierce Brosnan' Votes='95' />
</PCS:StrawPoll>
</form>
получить:

И когда мы нажмем на кнопку vote, изображение изменится на следующее:

Альтернативно, в основном для целей тестирования, можно выводить результаты и кнопки голосования одновременно, и разрешить подавать несколько голосов.
Код ASP.NET вовлечен явно в задание свойства Name
и Votes
для каждого варианта Option
. Это прекрасно подходит для данного примера, хотя можно предвидеть, что более развитая версия этого элемента управления соединится с данными для получения результатов. Однако здесь это рассматриваться не будет, так как может оказаться достаточно сложным.
При анализе кода ASP.NET такие структуры интерпретируются согласованным образом: каждый управляющий элемент-потомок интерпретируется способом, который определен в классе-построителе элемента управления, связанным с элементом управления предком. Этот построитель элемента управления, код которого мы скоро увидим, обрабатывает все вложенное внутрь элемента управления, с которым он связан, включая литеральный текст.
Нам нужно создать два элемента управления: Option
— для хранения отдельных вариантов выбора и StrawPoll
, который будет содержать и выводить элемент управления выборочного опроса. Оба эти элемента управления будут помещены в новый файл исходного кода: StrawPoll.cs
.
Элемент управления Option
Для начала создадим элементы управления Option, каждый из которых будет содержать имя варианта выбора и количество голосов, поданных за этот вариант выбора. Кроме того, эти элементы управления будут поддерживать кнопки голосования и обрабатывать все сделанные нажатия этих кнопок.
Поэтому нам потребуется:
□ Код для свойств Name
и Votes
(хранимых в ViewState
)
□ Код инициализации в CreateChildControls()