Спонсор: Microsoft
Опубликован: 14.11.2006 | Доступ: свободный | Студентов: 5804 / 513 | Оценка: 4.18 / 3.74 | Длительность: 16:37:00
ISBN: 978-5-9556-0085-7
Лекция 5:

AutoPostBack. Привязка к данным. Коллекции. Проверка правильности вводимых данных

< Лекция 4 || Лекция 5: 123 || Лекция 6 >
Аннотация: Привязка к данным с помощью коллекций. Примеры на использование коллекций ArrayList, Hashtable. Элементы управления группы Validation.

Свойство AutoPostBack

Программирование в ASP .NET ориентировано на события. События на странице (например нажатие на кнопку) обрабатываются на сервере. Изменения в тексте поля редактирования, выбора опции в списке, нажатие на флажок или переключатель не вызывают немедленной отправки на сервер. Этого можно добиться, если установить свойство AutoPostBack для этих элементов.

Если AutoPostBack установлен для элемента управления TextBox, то для него будет вызываться событие TextChanged, как только поле потеряет фокус или будет нажата клавиша Enter. Чтобы это свойство работало, браузер должен поддерживать ECMAScript (стандарт JavaScript, принятый Европейской ассоциацией производителей компьютеров).

Источником данных для элементов управления могут служить таблицы данных. Давайте разберем пример, входящий в состав Visual StudioCarSelectorSample. Действие происходит в электронном магазине автомобилей. Имеются разные марки машин, причем для каждой марки имеются несколько моделей. При выборе марки машины в первом списке во второй список автоматически грузятся соответствующие модели:

Brand Buick Chevrolet Pontiac Toyota Mileage Features
Power seat
Buick Century Impala Grand Am Avalon 0-10000 Leather seat
Chevrolet LeSabre Malibu Grand Prix Camry 10000-20000 Sun roof
Pontiac Park Avenue Metro Montana Camry Solara 20000-30000 CD player
Toyota Regal Prizm Sunfire Celica 30000 and more ABS

Все данные, используемые на этой странице, собраны в таблицу. Для хранения такой таблицы существует класс DataTable. Таблица состоит из столбцов — DataColumn и строк DataRow. Класс DataView позволяет создавать различные представления данных таблицы. Первый столбец служит источником данных списка марок. В зависимости от выбранной модели, в список моделей загружается одна из 2-5 колонок.

Вначале создается таблица:

Cars = new DataTable();
Cars.Columns.Add(new DataColumn("Brand", typeof(string)));

Здесь вызывается один из конструкторов DataColumn. Первый аргумент — название колонки, второй — тип:

CarRow = Cars.NewRow();

Создается новая строка таблицы. Ячейка таблицы задается с помощью индекса строки:

CarRow[6]= "Power seat";

И строка добавляется в таблицу:

Cars.Rows.Add(CarRow);

У выпадающего списка марок установлено свойство AutoPostBack. Это значит, что страница автоматически подается на сервер, когда в этом списке меняется выбранный элемент.

В обработчике выбора нового элемента вначале выясняется, какой элемент выбран:

string selected = DropDownList1.SelectedItem.Value;

В операторе switch происходит переключение второго списка на один из столбцов таблицы заданием свойств DataTextField и DataValueField, где DataTextField — текст, отображаемый в списке, а DataValueField — выбранное значение. В данном случае, как часто бывает, они одинаковы.

Привязка к данным

Некоторые элементы управления: списки, таблицы и другие — имеют свойство DataSource, которое отвечает за привязку к данным. Тип этого свойства — object, то есть он может быть любым, но должен реализовывать интерфейс IEnumerable. Часто значениями этого свойства назначают коллекции. В таком случае нет нужды добавлять значения вручную. Свойство DataSource может быть привязано к коллекциям, поддерживающим интерфейсы IEnumerable, ICollection или IListSource. Источником данных также могут быть XML-файлы, базы данных. Вызовом метода DataBind данные привязываются к элементу управления. Метод Page.DataBind вызывает привязку данных у всех элементов на странице.

Приведенный ниже выпадающий список помогает выбрать континент для путешествия. Источник данных — динамический массив ArrayList. Используйте его, если в программе происходит много вставок и удалений:

void Page_Load()
    {
        ArrayList ContinentArrayList = new ArrayList();
        ContinentArrayList.Add("Worldwide");
        ContinentArrayList.Add("America");
        ContinentArrayList.Add("Africa");
        ContinentArrayList.Insert(1, "Asia-Pacific");
        ContinentDropDownList.DataSource = ContinentArrayList;
        ContinentDropDownList.DataBind();
    } //End Page_Load()
....
<asp:DropDownList id="ContinentDropDownList" runat="server" />

Можно использовать в качестве источника данных хэш-таблицы ( Hashtable ). Хэш-таблицы — это структуры данных, которые были придуманы давно (см. том 3 "Искусства программирования" Д. Кнута), но программисты долгое время были вынуждены реализовывать их вручную. В языке PHP обычный массив и есть хэш-таблица. В библиотеке STL для языка С++ тоже есть тип map, в котором данные хранятся таким способом. Хэш-таблицы позволяют очень быстро найти значение по ключу. Индекс в коллекции вычисляется как простая хэш-функция ключа. В C# ключи используются как индексаторы. Используйте Hashtable, если в программе часто осуществляется поиск. Вставка и удаление происходят в нем медленно. Ключи могут быть произвольного типа. В классе Object определен виртуальный метод GetHashCode, он и применяется в Hashtable:

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void calSelectChange(Object sender, EventArgs e)
{
     lblShow.Visible = false;
     Hashtable hshDays = new Hashtable();
     hshDays[Convert.ToDateTime("2/6/2006")] = "Экзамен по алгеб-
ре";
     hshDays[Convert.ToDateTime("3/6/2006")] = "Экзамен по С#";
     hshDays[Convert.ToDateTime("4/6/2006")] = "Начало изучения 
курса ASP.NET";
     hshDays[Convert.ToDateTime("1/6/2006")] = "День защиты де-
тей";
     DateTime datDateIn;
     datDateIn = calDays.SelectedDate;
     if (Page.IsPostBack)
     {
         lblShow.Text = "На этот день назначен: ";
         lblShow.Text += hshDays[datDateIn];
         if (hshDays[datDateIn] == null)
             lblShow.Text = "Ничего не назначено";
         lblShow.Visible = true;
     }
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Попробуем хэш-таблицу</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <h3>Ежедневник
</h3>
Введите дату между 1/6/2006 и 30/6/2006
<asp:Calendar id="calDays" runat="server" 
OnSelectionChanged="calSelectChange"
VisibleDate="06/06/2006"
></asp:Calendar>
<br />
<br />
<asp:Label id="lblShow" runat="server"></asp:Label>
    </div>
    </form>
</body>
</html>

Здесь ключом хэш-таблицы является дата. Convert.ToDateTime конвертирует строку в тип даты. VisibleDate гарантирует, что на календаре будет июнь 2006 года. Если значений по ключу в таблице нет, то индексатор просто возвращает null. Значения можно вводить в любом порядке.

Хотелось бы добавить в страницу новую возможность введения новых записей. Можно ввести новые элементы управления — строку ввода и кнопку для подачи данных. При обработке нажатия на кнопку добавим в хэш-таблицу новое значение:

void Button1_Click(object sender, EventArgs e)
    {
        hshDays[calDays.SelectedDate]=TextBox1.Text;
    }

Эта страница не работает. Дело в том, что страница загружается заново, когда меняется дата. Хэш-таблица создается заново, и введенные в нее значения теряются. Как же решить эту проблему? Сделаем хэш-таблицу статической переменной:

static Hashtable hshDays;
void calSelectChange(Object sender, EventArgs e)
{
    DateTime datDateIn = calDays.SelectedDate;

    lblShow.Text = "На этот день назначен: ";
    lblShow.Text += hshDays[datDateIn];
    if (hshDays[datDateIn] == "")
        lblShow.Text = "Ничего не назначено";
}
void Page_Init()
{
    if (!Page.IsPostBack)
    {
        hshDays=new Hashtable();
        hshDays[Convert.ToDateTime("2/6/2006")] = "Экзамен по ал-
гебре";
        hshDays[Convert.ToDateTime("3/6/2006")] = "Экзамен по 
С#";
        hshDays[Convert.ToDateTime("4/6/2006")] = "Начало изуче-
ния курса ASP.NET";
        hshDays[Convert.ToDateTime("1/6/2006")] = "День защиты 
детей";
        Session["Diary"]= hshDays;
     }
}


void Record(Object sender, EventArgs e)
{
    DateTime datDateIn = calDays.SelectedDate;
    hshDays[datDateIn]= Entrance.Text;
    lblShow.Text = hshDays[datDateIn].ToString();
}
< Лекция 4 || Лекция 5: 123 || Лекция 6 >
Алексей Савельев
Алексей Савельев

https://technet.microsoft.com/en-us/library/ms143221(v=sql.105).aspx

Денис Прокофьев
Денис Прокофьев

Везде написано, что это самый независимый и простой в использовании навигационный элемент управления, что он работает сразу с web.sitemap и не требует определения SiteMapDataSource.

Моя карта сайта состоит из двух страниц, вложенных друг в друга. asp:Menu, asp:TreeView отбображаются как ожидалось, а вот asp:SiteMapPath - нет. Он не виден нигде. Однако на его месте формируется разметка: <span id="SiteMapPath1"><a href="#SiteMapPath1_SkipLink" style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden;">Проход по ссылкам навигации</a><a id="SiteMapPath1_SkipLink"></a></span> - т.е. элемент отрабатывает.

В словах xHTML это выглядит так: <asp:SiteMapPath ID="SiteMapPath1" runat="server" />. Причем не важно - внутри тега form или снаружи - всегда одинаково.

Т.к. другие нав. ЭУ работают через простой источник данных без ошибок, делаю вывод - карта составлена правильно. ИД: <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />

Карта: <?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
  <siteMapNode url="~/L11_1_simplePage.aspx" title="Страница 1"  description="Простая страница 1." >
    <siteMapNode url="~/L11_1SimplePage2.aspx" title="Страница 2"  description="Простая страница 2" />
  </siteMapNode>
</siteMap>

Почему так происходит? Вроде делаю все по примерам. VS Community 2015. NetFramework в проекте: v4.0.30319

Анна Малова
Анна Малова
Азербайджан, Баку
Дмитрий Крюков
Дмитрий Крюков
Россия, Москва