KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Симон Робинсон - C# для профессионалов. Том II

Симон Робинсон - C# для профессионалов. Том II

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Симон Робинсон, "C# для профессионалов. Том II" бесплатно, без регистрации.
Перейти на страницу:

 }

}

Здесь мы переопределяем метод GetChildControlType() базового класса ControlBuilder чтобы он возвращал тип класса Option в ответ на тег с именем <Option>. Фактически, чтобы все работало в максимальном количестве ситуаций, мы ищем любое имя тега, которое оканчивается строкой "option" с буквами в верхнем или нижнем регистре.

Мы переопределяем также метод AppendLiteralString() так, чтобы любой промежуточный текст, включая пробелы, игнорировался и не вызывал никаких проблем.

Когда это сделано в предположении, что в StrawPoll нет никаких других элементов управления, мы будем иметь все элементы управления Option содержащимися в коллекции Controls из StrawPoll. Эта коллекция не будет содержать никаких других элементов управления.

Отметим, что построитель элементов управления использует коллекцию атрибутов. Чтобы использовать это добавим следующую инструкцию using в пространство имен:

using System.Collections;

Стиль StrawPoll

Прежде чем перейти к рассмотрению самого класса StrawPoll, необходимо рассмотреть еще один вопрос проектирования. StrawPoll должен выводиться в трех формах:

□ Только кнопки для голосования

□ Только результаты

□ Кнопки для голосования и результаты

Для этого можно определить перечисление, которое затем использовать как свойство элемента управления StrawPoll:

public enum pollStyle {

 voteonly, valuesonly, voteandvalues

}

Как мы видели ранее, свойства, которые являются перечислениями, легко использовать, и мы можем применять текстовые имена в качестве значений атрибутов в ASP.NET.

Элемент управления StrawPoll

Теперь соберем все вместе. Для начала определим два свойства: Title дли вывода заголовка в элементе управления и PollStyle для хранения перечисления типа вывода. Оба они будут использовать ViewState для сохранения состояния:

[ ControlBuilderAttribute (typeof (StrawPollControlBuilder)) ]

[ ParseChildren(false) ]

public class StrawPoll : System.Web.UI.WebControls.WebContol, INamingContainer {

 private string title = "Straw Poll";

 private pollStyle currentPollStyle = pollStyle.voteandvalues;


 public string Title {

  get {

   return title;

  }

  set {

   title = value;

  }

 }


 public pollStyle PollStyle {

  get {

   return currentPollStyle;

  }

  set {

   currentPollStyle = value;

  }

 }

}

Остальная часть этого класса посвящена методу Render(). Он будет выводить весь элемент управления выборочного опроса вместе со всеми вариантами выбора, принимая в расчет используемый стиль опроса. Мы выводим кнопки голосования, вызывая метод RenderControl() производных элементов управления Option, и выводим результаты опроса графически и численно с помощью свойств Votes производных элементов управления Option для создания простого кода HTML.

Код, прокомментированный для ясности, будет выглядеть следующим образом:

protected override void Render(HtmlTextWriter writer) {

 Option CurrentOption;

 long iTotalVotes = 0;

 long iPercentage = 0;

 int iColumns = 2;

 // Начало таблицы, изображение таблицы

 if (currentPollStyle == pollStyle.voteandvalues) {

  iColumns = 3;

 }

 writer.Write("<TABLE border='1' bordercolor='black' bgcolor='#DDDDEB'" +

  " width= '90%' cellpadding='1' cellspacing='1'" + " align='center'>");

 writer.Write("<TR><TD colspan='" + iColumns + align='center'"

  + " bgcolor='#FFFFDD'>");

 writer.Write("<B>" + title + "</B></TD></TR>");

 if (Controls.Count == 0) {

  // текст по умолчанию, когда нет вариантов выбора

  writer.Write("<TR><TD bgcoLor='#FFFFDD'>No options to" + " display.</TR></TD>");

 } else {

  // Получить общее число голосов

  for (int iLoop = 0; iLoop < Controls.Count; iLoop++) {

   // Получить вариант выбора

   currentOption = (Option)Controls[iLoop];

   // Просуммировать результаты голосования

   iTotalVotes += currentOption.Votes;

  }

  // Вывести каждый вариант выбора

  for (int iLoop = 0; iLoop < Controls.Count; iLoop++) {

   // Получить вариант выбора

   currentOption = (Option)Controls[iLoop];

   // Поместить имя варианта выбора в первый столбец

   writer.Write("<TR><TD bgcolor='#FFFFDD' width="15%'> " +

    currentOption.Name + " </TD>");

   // Добавить вариант голосования во второй столбец,

   // если требуется

   if (currentPollStyle != pollStyle.valuesonly) {

    writer.Write("<TD width='1%' bgcolor='#FFFFDD'>"

     + "<FONT Color='#FFFVDD'>.</FONT>");

    currentOption.RenderControl(writer);

    writer.Write("<FONT Color = '#FFFFDD'>.</FONT></TD>");

   }

   // Поместить график, значение и проценты в третьем столбце,

   // если требуется

   if (currentPollStyle != pollStyle.voteonly) {

    if (iTotalVotes > 0) {

     iPercentage = (currentOption.Votes * 100) / iTotalVotes;

    } else {

     iPercentage = 0;

    }

    writer.Write("<ТD bgcolor='#FFFFDD'><TABLE width='100%'>"

     + "<TR><TD><TABLE border='1' bordercolor= 'black' "

     + " width= '100%' cellpadding='0' " + " cellspacing='0'>");

    writer.Write("<TR><TD bgcolor='red' width='" + iPercentage

     + "%'><FONT соlor='red'>.</FONT></TD>");

    writer.Write<"TD bgcolor='white' width='" + (100-iPercentage) +

     "%'><FONT color='white'>." +

     "</FONT></TD></TR></TABLE></TD>");

    writer.Write("<TD width='75'>" + сurrentOption.Votes +

     " (" + iPercentage + "%)</TD><TR></TABLE></TD>");

   }

   // Конец строки

   writer.Write("</TR>");

  }

  // показать общее тело голосов, если выводятся значения

  if (currentPollStyle != pollStyle.voteonly) {

   writer.Write("<TR><TD bgcolor='#FFFFDD' colspan='" +

    iColumns + "'>Total votes cast: " + iTotalVotes + "</TD></TR>");

  }

 }

 // Завершить таблицу

 writer.Write("</TABLE>");

}

Если выборочный опрос выводится в режиме voteonly, то голосование должно инициировать изменение изображения в режиме valuesonly. Чтобы сделать это, нам потребуется небольшое изменение в обработчике кнопки голосования в классе Option:

protected void btnVote_Click(object sender, System.EventArgs e) {

 Increment();

 StrawPoll parent = (StrawPoll)Parent;

 if (parent.PollStyle == pollStyle.voteonly) {

  parent.PollStyle = pollStyle.valuesonly;

 }

}

Теперь все готово к проведению голосования.

Добавление обработчика событий

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

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

public event EventHandler Voted;


protected void OnVoted(EventArgs e) {

 Voted(this, e);

}

Тогда, как только нам понадобиться инициировать событие, мы просто вызываем метод OnVoted(), передавая аргументы события.

Когда вызывается OnVoted(), инициируется событие, в соответствии с которым может действовать пользователь. Чтобы сделать это, пользователю необходимо зарегистрировать обработчик событий для этого события:

strawPoll1.Voted += new EventHandler(this.StrawPoll1_OnVoted);

Пользователь должен также предоставить код обработчика strawPoll1_OnVoted(). Мы слегка расширим этот метод, добавляя специальные аргументы для события, чтобы сделать доступным элемент управления Option, который инициирует событие. Назовем наш объект специального аргумента OptionEventArgs и определим его в StrawPoll.cs следующим образом:

public class OptionEventArgs : EventArgs {

 public Option originatingOption;

}

Добавляем дополнительное открытое поле в существующий класс EventArgs. Так как мы изменили используемые аргументы, нам потребуется также специализированная версия представителя EventHandler, которая может объявляться в пространстве имен PCSCustomWebControls следующим образом:

public delegate void Option EventHandler(object sender, OptionEventArgs e);

Можно использовать эти примеры в StrawPoll следующим образом:

public class StrawPoll : System.Web.UI.WebControls.WebControl, INamingContainer {

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*