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

Элементы-потребители данных ASP .NET 2.0

< Лекция 8 || Лекция 9: 12345 || Лекция 10 >

События GridView

Элементы управления, описываемые в этой лекции, имеют по два события для каждой операции. Одно из них возникает до начала выполнения операции, второе — после. Например, RowUpdated — когда пользователь обновляет запись, происходит событие RowUpdating, выполняется команда Update источника данных и затем происходит событие RowUpdated.

В RowUpdating мы можем узнать, какая информация посылается источнику данных и изменить ее, а, возможно, и отменить обновление.

В обработчике события RowUpdating передается аргумент типа GridViewUpdateEventArgs. Его свойство RowIndex определяет индекс текущей строки. Чтобы отменить операцию, установите свойство Cancel в true.

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

protected void GridView1_RowUpdating(Object sender, 
GridViewUpdateEventArgs e)
    {
        foreach (DictionaryEntry entry in e.NewValues)
        {
            if(entry.Value!=null)
            e.NewValues[entry.Key] = 
Server.HtmlEncode(entry.Value.ToString());
        }
    }

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

<asp:Label ID="ErrorLabel" runat="server" Text=" " Font-
Bold="True" ForeColor="Red"></asp:Label><br />

Перехватываем и обрабатываем ошибку редактирования:

protected void GridView1_RowUpdated(object sender, 
GridViewUpdatedEventArgs e)
    {
        if (e.Exception != null)
        {
            ErrorLabel.Text = e.Exception.Message;
            e.ExceptionHandled = true;
        }
    }

Другие парные события:

RowDeleting RowDeleted
PageIndexChanged PageIndexChanging
SelectedIndexChanged SelectedIndexChanging
Sorted Sorting

В программном режиме можно манипулировать коллекцией Rows, состоящей из объектов типа GridViewRow. Строки GridView имеют свойства RowState и RowType. RowState может принимать значения из перечисления: Normal, Edit, Alternate, Insert и Selected.

Данные, хранящиеся в строке, можно получить из коллекции DataItem, которая индексируется названиями полей.

Создайте страницу Products.aspx и опять с помощью drag-and-drop таблицы Products создайте GridView. Посмотрим, как можно в обработчике события RowDataBound изменять внешний вид таблицы. Пусть нужно установить различные цвета фона в зависимости от категории товара. Добавим обработчик RowDataBound. У аргумента события есть свойство Row, которое позволяет манипулировать строкой GridView:

protected void GridView1_RowDataBound(object sender, 
GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            switch ((int)((DataRowView)e.Row.DataItem)["CategoryID"])
            {
                case 1: e.Row.BackColor = Color.AliceBlue; break;
                case 2: e.Row.BackColor = Color.AntiqueWhite; break;
                case 3: e.Row.BackColor = Color.FloralWhite; break;
                case 4: e.Row.BackColor = Color.Beige; break;
                default:
                    e.Row.BackColor = Color.White; break;
            }
        }
    }

Можно сделать так, чтобы стиль строк менялся при наведении курсора мыши:

protected void GridView1_RowDataBound(object sender, 
GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        e.Row.Attributes["onmouseover"] = 
"this.style.backgroundColor='#FFE4B5'";
        e.Row.Attributes["onmouseout"] = 
"this.style.backgroundColor='#FFFFFF'";
    }
}

Наш GridView выводит числовые значения полей CategoryId и SupplierId. Но, конечно, пользователю нужны названия, и брать их приходится из других таблиц. Можно связать GridView и с представлением ( View ), но представления не поддерживают редактирование.

Установим свойство AutoGenerateEditButton в True и превратим столбец CategoryId в TemplateField, а также добавим второй источник данных:

<asp:SqlDataSource ID="SqlDataSource2" runat="server" 
        ConnectionString="<%$ 
ConnectionStrings:NorthwindConnectionString %>" 
        SelectCommand="SELECT [CategoryID], [CategoryName] FROM 
[Categories] ORDER BY [CategoryName]">
    </asp:SqlDataSource>

Visual Studio 2005 сгенерировал шаблон, который предстоит изменить на такой:

<asp:TemplateField HeaderText="Категория" 
SortExpression="CategoryID">
    <EditItemTemplate>
        <asp:DropDownList  ID="CatDropDownList" runat="server" 
            DataSourceID="SqlDataSource2" 
DataValueField="CategoryId" 
            DataTextField="CategoryName" SelectedValue=<%# 
Bind("CategoryId") %>>
        </asp:DropDownList >
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="CatLabel" runat="server" ></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

При этом в режиме отображения строки в колонке "Категория" ничего не выводится. Чтобы получить нужное значение из таблицы Categories, напишем обработчик события RowDataBound:

protected void GridView1_RowDataBound(object sender, 
GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    if (e.Row.RowState == DataControlRowState.Normal ||
        e.Row.RowState == DataControlRowState.Alternate)
    {
        // получить данные из SqlDataSource2
        DataView ds = 
(DataView)SqlDataSource2.Select(DataSourceSelectArguments.Empty);
        // получить значение текущей категории
        DataRowView view = (DataRowView)e.Row.DataItem;
        int catid = (int)view.Row[3];
        // отфильтровать нужную категорию
        ds.RowFilter = string.Format("CategoryID='{0}'", catid);
        Label Text1 = (Label)e.Row.FindControl("CatLabel");
        Text1.Text = ds[0].Row["CategoryName"].ToString();
     }
}

Точно так же можно поступить с полем SupplierID.

< Лекция 8 || Лекция 9: 12345 || Лекция 10 >
Алексей Савельев
Алексей Савельев

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