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

Привязка данных ADO.NET

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

Некоторые элементы управления библиотеки .NET Framework, служащие для отображения данных, позволяют привязать сразу несколько своих дочерних элементов к источнику данных. К ним относятся прежде всего списковые элементы управления:

  • Все списковые элементы управления, которые генерируют свой HTML-код с использованием дескриптора <select>, включая HtmlSelect, ListBox и DropDownList
  • Элементы управления CheckBoxList и RadioButtonList, генерирующие HTML-код своих дочерних элементов в виде флажков или переключателей
  • Элемент управления BulletedList, создающий нумерованный или маркированный список

Все они наследуют от System.Web.UI.WebControls.ListControl, который содержит свойства, необходимые для привязки множественного значения. Эти свойства приведены в таблице

Свойства ListControl для привязки множественного значения
Свойство Описание
DataSource Подключает ссылку на объект с данными (для загрузки методом DataBind() ), имеющими
DataSourceID Присоединяется к уже загруженному объекту данных. Используется как альтернатива свойству DataSource. Оба свойства сразу применять нельзя
DataTextField Содержит наименование поля (столбца) таблицы, значения которого будут отображаться списком
<select size="3" name="ListBox1" id="ListBox1">
    <option value="1">Text1</option>
    <option value="2">Text2</option>
</select>

DataValueField Содержит наименование поля (столбца) таблицы, значения которого будут загружены в список как атрибуты value, но пользователь их не увидит
<select size="3" name="ListBox1" id="ListBox1">
    <option value="1">Text1</option>
    <option value="2">Text2</option>
</select>

В свою очередь, класс ListControl наследует метод DataBind() от класса System.Web.UI.WebControls.BaseDataBoundControl, иницирующий привязку.

Для примера привязки множественного значения спроектируем страницу, в которой в качестве объекта, имитирующего источник данных, используем класс Hashtable (hash - мусор). Он реализует интерфейс System.Collections.Generic.IDictionary, имеющий шаблонный метод IDictionary<TKey, TValue>.Add(TKey, TValue).

  • Добавьте к приложению страницу с неразделяемым кодом и именем RepeatedValueBinding.aspx
  • Заполните интерфейсную часть страницы следующим кодом
<%@ Page Language="C#" %>
    
<script runat="server">
    
</script>
    
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <select runat="server" id="Select1" 
            datatextfield="Key" datavaluefield="Value" size="3" />
        <select runat="server" id="Select2" 
            datatextfield="Key" datavaluefield="Value" />
        <asp:ListBox runat="server" ID="ListBox1" 
            DataTextField="Key" DataValueField="Value" Rows="3" />
        <asp:DropDownList runat="server" ID="DropDownList1" 
            DataTextField="Key" DataValueField="Value" />
        <asp:RadioButtonList runat="server" ID="RadioButtonList1" 
            DataTextField="Key" DataValueField="Value" />
        <asp:CheckBoxList runat="server" ID="CheckBoxList1"
            DataTextField="Key" DataValueField="Value" />
        <br />
        <asp:Button runat="server" ID="GetSelection" Text="Получить выделенное" />
        <br />
        <br />
        <asp:Literal runat="server" ID="Result" EnableViewState="false" />
    </div>
    </form>
</body>
</html>

Объявления первых двух статических списков нужно набирать вручную, чтобы подсказчик кода допускал к их атрибутам. Элемент управления Literal все-равно будет заполняться при каждой обратной отсылке и отображать значения свойств выбранных дочерних элементов. Поэтому, чтобы не таскать состояние этого элемента с сервера на броузер и обратно, отключим у него свойство сохранения состояния.

  • Переведите редактор страницы в режим Design и двойным щелчком мыши на свободном месте создайте обработчик Page_Load(), который заполните так
protected void Page_Load(object sender, EventArgs e)
{
    if (!this.IsPostBack)
    {
        // Создать источник данных (коллекцию) с тремя элементами
        Hashtable ht = new Hashtable(3);
        
        // Добавить в коллекцию элементы по схеме: Add(Key, Value)
        ht.Add("Иванов", "Value1");
        ht.Add("Петров", "Value2");
        ht.Add("Сидоров", "Value3");
        
        // Связать элементы управления с источником данных
        Select1.DataSource = ht;
        Select2.DataSource = ht;
        ListBox1.DataSource = ht;
        DropDownList1.DataSource = ht;
        RadioButtonList1.DataSource = ht;
        CheckBoxList1.DataSource = ht;
        
        // Загрузить данные в элементы управления
        this.DataBind();
    }
}

Источник данных Hashtable можно представить таблицей из двух столбцов. Первый столбец считается Key, второй - Value.

  • Запустите страницу, чтобы проверить работу механизма привязки множественного значения к списковым элементам управления

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

  • Создайте обработчик для кнопки Button и заполните его следующим кодом
protected void GetSelection_Click(object sender, EventArgs e)
    {
        try
        {
            Result.Text += "<li>В Select1 выбрано: "
                        + "(\""
                        + Select1.Items[Select1.SelectedIndex].Text // Key
                        + "\", \""
                        + Select1.Value + "\")";                    // Value
            Result.Text += "<li>В Select2 выбрано: "
                        + "(\""
                        + Select2.Items[Select2.SelectedIndex].Text // Key
                        + "\", \""
                        + Select2.Value + "\")";                    // Value
            Result.Text += "<li>В ListBox1 выбрано: "
                        + "(\""
                        + ListBox1.SelectedItem.Text                // Key
                        + "\", \""
                        + ListBox1.SelectedItem.Value + "\")";      // Value
            Result.Text += "<li>В DropDownList1 выбрано: "
                        + "(\""
                        + DropDownList1.SelectedItem.Text           // Key
                        + "\", \""
                        + DropDownList1.SelectedItem.Value + "\")"; // Value
            Result.Text += "<li>В RadioButtonList1 выбрано: "
                        + "(\""
                        + RadioButtonList1.SelectedItem.Text          // Key
                        + "\", \""
                        + RadioButtonList1.SelectedItem.Value + "\")";// Value
    
            // Проверяем флажки
            int checkedCount = 0;
            string checkString = "";
            foreach (ListItem check in CheckBoxList1.Items)
            {
                if (check.Selected)
                {
                    checkString += "(\""
                                + check.Text                        // Key
                                + "\", \""
                                + check.Value + "\"); ";            // Value
                    checkedCount++;  // Считем выделенные флажки
                }
            }
            if (checkedCount == 0)
                Result.Text += "<li>В CheckBoxList1 ничего не выбрано!";
            else
                Result.Text += "<li>В CheckBoxList1 выбрано: " + checkString;
        }
        catch
        {
            Result.Text = "<h1 style='color:Red'>Выберите в каждом элементе</h1>";
        }
    }

Разница в коде доступа к свойствам списков между серверными элементами управления и статическими объясняется подгонкой фирмой Microsoft HTML-классов под ранее разработанные дескрипторы <select>.

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