ASP.Net. Лекція 8. Елементи-споживачі даних (Data-Bound Controls) (вихідні коди)

Лекція 7

Споживачі даних відображають дані, отриману з класів джерел даних. Вони дають більшу функціональність. Наприклад, елемент управління GridView може не лише показувати дані, але і сортувати, вибирати, редагувати їх. Якщо цієї функціональності недостатньо, її можна розширити, написавши власні обробники подій.


Елементи, які можуть бути пов'язані з елементами-джерелами даних, різноманітні. По-перше, це вже добре знайомі DropDownList, ListBox, CheckBoxList, RadioButtonList, BulletedList. Однак, у всіх них необхідно в якості джерела даних вказувати не DataSource, а DataSourceID. Всі ці елементи відображати можуть тільки 1 поле, вказане в DataTextField, з можливістю завдання другого в якості індексного у властивості DataValueField.






 <Asp: SqlDataSource ID = "SqlDataSource3" runat = "server" ConnectionString ="<%$ ConnectionStrings: NorthwindConnectionString%> "
SelectCommand = "SELECT [CategoryName], [CategoryID] FROM [Categories]">
</asp:SqlDataSource>
<Asp: CheckBoxList ID = "CheckBoxList1" runat = "server" AppendDataBoundItems = "True" DataSourceID = "SqlDataSource3"
DataTextField = "CategoryName" DataValueField = "CategoryID">
</asp:CheckBoxList> 
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="SqlDataSource3" DataTextField="CategoryName">
</asp:DropDownList>
<Asp: BulletedList ID = "BulletedList1" runat = "server" BulletStyle = "UpperRoman" DataSourceID = "SqlDataSource3"
DataTextField = "CategoryName" DataValueField = "CategoryName">
</asp:BulletedList>

AppendDataBoundItems – це нова властивість. Воно дозволяє комбінувати дані з елемента-джерела з даними, статично оголошеними на сторінці.


Дуже цікаві елементи управління Repeater і DataList. Вони дозволяють управляти відображенням даних за допомогою шаблонів.


Синтаксис динамічного зв'язування


Можна отримувати дані, пов'язані з елементом управління, в його декларації на сторінці. Це робиться за допомогою різновиду блоку відображення. У ранніх версіях ASP. NET за допомогою такого механізму можна було тільки читати, але тепер можливо і двостороннє зв'язування. Особливо це важливо в елементах управління, які використовують шаблони. Хоча DataGrid і GridView автоматично відображають дані, але і в них для створення потрібних ефектів використовуються стовпці-шаблони.


Для прив'язки до даних використовуються роздільники <% #%>. В життєвому циклі кожного елемента управління настає подія DataBinding, під час якого і обчислюються всі вирази, укладені в цей тег.


Якщо у функції Page_Load ми писали






 ContinentDropDownList.DataSource = ContinentArrayList;

То на сторінці це можна зробити за допомогою






 <Asp: DropDownList id = "ContinentDropDownList" datasource ="<%# ContinentArrayList%> "runat =" server ">

У ASP. NET 1.x дані читалися в об'єкти DataSet або DataReader, після чого викликався DataBind. в ASP.NET 2.0, якщо ж встановлено властивість DataSourceID, то подія DataBinding викликається автоматично.


У створеному в ASP.NET класі сторінки в обробнику цієї події для ContinentDropDownList буде виконуватися код


datasource = ContinentArrayList;


При цьому в локальному кеші створюється копія прочитаних даних. Для елементів Repeater, DataList, DataGrid синтаксис прив'язки даних розбирається у події ItemDataBound, для GridView – у RowDataBound. Ці події викликаються стільки разів, скільки записів у джерелі даних. Кожного разу, коли ASP.NET зустрічає ці роздільники в шаблоні, всередині елемента Item (RepeaterItem, DataListItem, DataGridItem) створюється елемент типу DataBoundLiteralControl, всередині якого записується вираз всередині роздільників. У обробнику події DataBinding цього елемента визначено мінлива Container, яка вказує на цей самий Item, тобто секцію елемента. Класи Item зберігають дані у властивості DataItem. Тому в шаблонах доступ до даних відбувається за допомогою синтаксису Container.DataItem.


Можливий синтаксис для доступу до поля






 <% # ((System.Data.DataRowView) Container.DataItem) ["City"]%>

у разі, коли дані отримані з DataReader,






 <% # ((System.Data.IDataRecord) Container.DataItem) ["City"]%>

у разі, коли дані отримані з DataSet,






  <%# DataBinder.Eval(Container.DataItem, “City”) %>

Цей спосіб замінює обидва попередні, так як DataBinder за допомогою статичної функції Eval сам визначає тип джерела і відповідно його обробляє. Метод Eval перевантажений, його другий варіант приймає аргумент для форматування даних.






  DataBinder.Eval(Container.DataItem, “Age”,”{0:2d}”)

У ASP. NET 2.0 синтаксис можна спростити і написати






  <%# Eval(“City”)%>

У нових елементах управління GridView, DetailsView, FormView, де підтримується двонаправлений висновок даних, можна викликати метод Bind. Його використовують в шаблонах редагованих рядків.






 <Asp: TextBox ID = "EditFirstNameTextBox" RunAt = "Server" Text ="<%# Bind ("FirstName")%> "/>

Repeater


Repeater в перекладі означає «той, хто повторює». Серед його значень «студент-другорічник» і «злодій-рецидивіст». Адже вони теж повторюють, те що роблять. Але це погані значення, а хороше – елемент-повторювач заданого шаблону для всіх полів джерела даних.


Шаблон – це безліч тегів HTML і серверних елементів керування, які задають зразок для відображення складової частини складного елементу управління. DataGrid може використовувати шаблони чи ні, але Repeater без них існувати не може, сам по собі він не має візуального представлення. Таким чином, програміст сам визначає його зовнішній вигляд. Крім DataSourceID і DataMember, власних властивостей у нього немає. Тому в програміста є повний контроль над тим, як виводиться Repeater.


Як мінімум, повинен бути описаний шаблон ItemTemplate. HeaderTemplate відображається один раз на початку відтворення ріпітера, FooterTemplate в кінці, SeparatorTemplate між відображенням кожного пункту, AlternatingItemTemplate – Для парних пунктів. Усі серверні елементи управління в шаблоні містяться цілком, тому щоб отримати таблицю, використовують прості теги HTML. Наприклад, що відкриває тег <table> поміщають в HeaderTemplate, а закриває в FooterTemplate.


У цьому прикладі складаються характеристики співробітників






 <asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
<HeaderTemplate> <Asp: Label runat = "server" ID = "Header1"
        BackColor=”DarkOrange” ForeColor=”ActiveCaptionText”
Font-Bold = "true" Font-Underline = "true" Font-Size = "Large">
        We present our valued Employees!</asp:Label>
        <table>
    </HeaderTemplate>
    <ItemTemplate>
        <tr>
         <td>
<asp:Panel ID="Panel1" runat="server" BackColor="LightPink">
<Asp: Image ID = "Photo" runat = "server" ImageUrl = <% # Eval ("PhotoPath ")%>/>
               <%# Eval( “TitleOfCourtesy”) %>
<% # DataBinder.Eval (Container.DataItem, "FirstName")%>
<% # DataBinder.Eval (Container.DataItem, "LastName")%>
was born in <% # Eval ("BirthDate", "{0: dd.MM.yyyy}")%>. <p>
<% # Eval ("TitleOfCourtesy"). ToString () == "Mr." / / Eval ("TitleOfCourtesy"). ToString () == "Dr." ? "He": "She"%>
               lives in beautiful city
<% # ((System.Data.DataRowView) Container.DataItem) ["City "]%>,
               <%# Eval( “Region”) %> in
<% # DataBinder.Eval (Container.DataItem, "Country") %>.</ p>
<p> We appreciate <% # Eval ("TitleOfCourtesy"). ToString () == "Mr." / /
Eval ("TitleOfCourtesy"). ToString () == "Dr." ? "His": "her"%> work as <% # Eval ("Title") %>.</ p>
<p> <% # DataBinder.Eval (Container.DataItem, "Notes")%> </ p>
            </asp:Panel>
         </td>
       </tr>
    </ItemTemplate>
    <FooterTemplate>
    </table></FooterTemplate>
</asp:Repeater>
<asp:SqlDataSource ID=”SqlDataSource1″ runat=”server”
ConnectionString ="<%$ ConnectionStrings: NorthwindConnectionString1%> "
SelectCommand = "SELECT * FROM [Employees]"> </ asp: SqlDataSource>

У браузері це виглядає так:



Зверніть увагу на умовні вирази:






 <% # Eval ("TitleOfCourtesy"). ToString () == "Mr." / / Eval ("TitleOfCourtesy"). ToString () == "Dr." ? "He": "She"%>

Цим досягається той ефект, що в пропозиції про чоловіка вживаються займенники чоловічого, а про жінку – жіночого роду. У таблиці немає поля для підлоги, але його можна обчислити за TitleOfCourtesy, який у чоловіків буває або "Mr.", або "Dr.".


Якщо потрібно змінити зовнішній вигляд всього шаблону, простіше всього помістити весь його вміст або весь елемент у Panel і визначити в ньому стилі.


За допомогою елемента управління Repeater можна створювати етикетки для конвертів, запрошення і так далі.


DataList


DataList має ті ж риси, що й Repeater, тобто виводить дані згідно шаблонах. Проте це більш багатий елемент керування. По-перше, він підтримує вибір, редагування, видалення і вставку. Тому список шаблонів поповнився SelectedItemTemplate і EditItemTemplate. Крім того, у нього є верхній і нижній колонтитули зі стилями HeaderStyle і FooterStyle.


По-друге, можна змінити способи відображення. За замовчуванням DataList виводить дані поколонно в таблиці. Властивість RepeatLayout встановлене як Flow, прибирає табличні теги з вихідного потоку. RepeatDirection змінює напрямок виводу з вертикального на горизонтальне. RepeatColumns задає кількість стовпців таблиці, за замовчуванням дорівнює 1.


DataList спадкоємець абстрактного класу BaseDataList, що успадкував WebControl. Тому у нього на відміну від Repeater, є візуальні властивості. При відображенні він являє собою таблицю, тому присутні властивості CellPadding і CellSpacing.


У DataList є шаблон за замовчуванням, Visual Studio 2005 і VWD створюють його у вигляді вертикально розташованих міток для кожного поля, а ліворуч від них текст з назвою поля. Щоб увійти в режим редагування шаблону, потрібно скористатися можливістю SmartTag – Edit Templates. Після того, як редагування закінчено, не забудьте вийти з режиму – End Template Editing.


Можна спроектувати цей елемент так, щоб в звичайному стані відображалася коротка інформація, а у вибраному стані – більше.


Подивимося приклад з Quickstarts:






      <asp:DataList id=”DataList1″ runat=”server”
        BorderColor=”black” BorderWidth=”1″
        GridLines=”Both” CellPadding=”3″
        Font-Names=”Verdana” Font-Size=”8pt”
        Width=”150px”
        HeaderStyle-BackColor=”#aaaadd”
        AlternatingItemStyle-BackColor=”Gainsboro”
        SelectedItemStyle-BackColor=”yellow”
        OnItemCommand=”DataList_ItemCommand”
     >
    <HeaderTemplate>
         Items
    </HeaderTemplate>
    <ItemTemplate>
<asp:LinkButton id="button1" runat="server" Text="Show details" CommandName="select" />
<% # DataBinder.Eval (Container.DataItem, "StringValue")%>
    </ItemTemplate>
    <SelectedItemTemplate>
      Item:
<% # DataBinder.Eval (Container.DataItem, "StringValue")%>
        <br>
      Order Date:
<% # DataBinder.Eval (Container.DataItem, "DateTimeValue", "{0: d}")%>
        <br>
      Quantity:
<% # DataBinder.Eval (Container.DataItem, "IntegerValue", "{0: N1}")%>
      <br>
    </SelectedItemTemplate>
</asp:DataList>

А обробник вибору запису такий:






 void DataList_ItemCommand (object Sender, DataListCommandEventArgs e) {
string cmd = ((LinkButton) e.CommandSource). CommandName;
        if (cmd == “select”)
            DataList1.SelectedIndex = e.Item.ItemIndex;
        BindList();
    }

Щоб реалізвать редагування, теж потрібно обробляти подія. Тому в ASP.NET 2.0 DataList краще використовувати для показу даних без редагування, а якщо потрібно редагування, використовувати елемент управління FormView.


Властивість DataKeyField є й у DataGrid, і у DataList. За допомогою нього відбувається зв'язування з ключовим полем таблиці даних.


DataGrid


Це дуже популярний елемент управління, і не дивно. Особливо багато він застосовувався в ASP.NET 1.x, але тепер його функції перекриваються GridView. Тим не менш його варто вивчити, тому що багато які його властивості схожі з властивостями GridView. DataGrid робить дуже легким подання табличної інформації, яка міститься в базах даних, файлах XML, або створюється вручну. Досить створити DataGrid, встановити властивість DataSource, і отримати готову таблицю на сторінці. Формат таблиці можна змінювати незалежно від даних. Дані можна сортувати, вибирати, редагувати.


У найпростішому варіанті потрібно встановити тільки властивість DataSource, його значенням може бути об'єкт, який реалізує інтерфейс IEnumerable, наприклад SqlDataReader, DataTable. При цьому на сторінці виводиться таблиця, де рядкам відповідають записи, а стовпцях поля.


Створимо простий XML-файл з табличною інформацією. Це будуть дані про лауреатів Нобелівської премії з літератури та фізики. Назвіть її nobel.xml.






  <?xml version=”1.0″ encoding=”utf-8″ ?>
<nobel>
  <phisics>
    <phisisist>
      <name>Basov</name>
      <nationality>Russia(USSR)</nationality>
    </phisisist>
    <phisisist>
      <name>Rentgen</name>
      <nationality>Germany</nationality>
    </phisisist>
    <phisisist>
      <name>Bor</name>
      <nationality> Denmark</nationality>
    </phisisist>
  </phisics>
  <literature>
    <writer>
      <name>Boris Pasternak</name>
      <nationality>Russia</nationality>
      <work>”Doctor Zhivago”</work>
      <winningdate>1958</winningdate>
    </writer>
    <writer>
      <name>Romain Rollan</name>
      <nationality>France</nationality>
      <work>”Jean-Cristophe”</work>
      <winningdate>1915</winningdate>
    </writer>
    <writer>
      <name>Gabriel Garsia Marquez </name>
      <nationality>Columbia</nationality>
      <work>”100 years of solitude”</work>
      <winningdate>1982</winningdate>
    </writer>
    <writer>
      <name>George Bernard Shaw</name>
      <nationality>Great Britain</nationality>
      <work></work>
      <winningdate>1925</winningdate>
    </writer>
  </literature>
</nobel>

Тут побудована трирівнева ієрархія. Вузол <nobel> повинен бути прочитаний у DataSet. Усередині нього є 2 вузла – один з даними про фізику, другий про літературу. Кожен з них буде поміщений в DataTable. Вузли <name>, <nationality>, <work>, <winningdate> вкладені в <literature> і повторюються для кожного письменника. Вони будуть лічені в DataColumns таблиці.


Чому вузол <work> </ work> у Шоу порожній? Як вважав сам Шоу, Нобелівську премію 1925 йому дали за те, що в цьому році він нічого не написав.


Через методи ReadXml, WriteXml DataSet може читати дані з XML-файлу.


Форма, яка читає інформацію з цього файлу:






  <%@ Page Language=”C#” Debug=”true” %>
<%@ Import Namespace=”System.Data” %>
<%@ Import Namespace=”System.Xml” %>
<script runat=”server”>
    void Page_Load()
    {
        String xmlFilename = Server.MapPath(“”) + ”
obel.xml”;
        DataSet newDataSet = new DataSet();
        newDataSet.ReadXml(xmlFilename);
        DataTable newDataTable = newDataSet.Tables[1];
        DataGrid1.DataSource = newDataTable;
        DataGrid1.DataBind();
    }
    void Page_Load()
    {
        if (!IsPostBack)
            bindData();
    }
</script>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
    <title>Data Grid Control example</title>
</head>
<body>
    <form runat=”server”>
<Asp: DataGrid id = "DataGrid1" runat = "server" CellSpacing = "10"
BorderWidth = "0" BackColor = "AliceBlue" EditItemIndex = "1">
<HeaderStyle BackColor="#AAAADD" Font-Size="20pt" Font-Bold = "True">
        </HeaderStyle>
        <AlternatingItemStyle BackColor=”#80FF80″ />
    </form>
</body>
</html>

Помінявши індекс у DataTable newDataTable = newDataSet.Tables [1] на 3, отримаємо сторінку з іншими даними – лауреатів премії з літератури.


За замовчуванням елемент DataGrid сам визначає кількість полів у джерелі даних і генерує колонки таблиці. Це визначається властивістю AutoGenerateColumns. З елементом управління DataGrid можуть бути пов'язані не всі типи даних. Підтримуються примітивні типи, рядки, DataTime і Decimal. Якщо в полі непідтримуваний тип, стовпець не буде створено. Якщо жодного підходящого поля немає, буде викинуто виняток.


DataGrid має заголовок (Header), який за замовчуванням видно, і нижній колонтитул (Footer). При автоматичної генерації в заголовку кожного стовпця показати назву поля.


Якщо AutoGenerateColumns встановити в False, можна самим управляти колонками і визначати більш складний його вид. У такому випадку треба включати в DataGrid елементи BoundColumn. Деякі властивості BoundColumn:


DataField визначає поле джерела даних.


DataFormatString задає формат виводу даних.


ReadOnly робить поле недоступним для редагування.


У заголовку і нижньому колонтитулі можна встановити будь-який текст, а в заголовку ще і картинку (HeaderText, FooterText, HeaderImageUrl).


У осередок генерується DataGrid таблиці вставляється LiteralControl, текст якого береться з джерела даних і форматується відповідно до DataFormatString. Для поточного рядка в комірці з'являється TextBox.


Є й інші типи колонок.


ButtonColumn відображає в кожному рядку командну кнопку. Якщо пов'язати її з полем, на кнопках будуть написи з цього поля.


EditCommandColumn показує кнопки для редагування.


HyperLinkColumn перетворює текст на гіперпосилання. Наприклад, поле PhotoPath можна показати в такій колонці, тоді клацання по посиланню покаже фотографію.


TemplateColumn дозволяє визначити шаблон відображення, як у DataList.


При бажанні можна програмно приховувати і показувати колонки, наприклад:






 DataGrid1.Columns [1]. Visible =! (DataGrid1.Columns [1]. Visible);

У елемента DataGrid є 7 властивостей, які задають стилі різних його частин або типів рядків. Всі вони мають тип TableItemStyle. Це AlternatingItemStyle, EditItemStyle, FooterStyle, HeaderStyle, ItemStyle, PagerStyle, SelectedItemStyle. Стилі утворюють ієрархію, тобто атрибут стиль, який вище в ієрархії, успадковує ті, які нижче, якщо він його не перевизначає. Порядок у ній такий:



  1. EditItemStyle – стиль поточного рядка;
  2. SelectedItemStyle – стиль вибраного рядка;
  3. AlternatingItemStyle це стиль кожного другого рядка.
  4. ItemStyle – стиль рядка за умовчанням
  5. ControlStyle – це всі властивості, які впливають на зовнішній вигляд елемента, наприклад BackColor. PagerStyle, FooterStyle, HeaderStyle теж його успадковують.

PagerStyle – це стиль пейджера, тобто номерів сторінок-гіперпосилань, при виборі яких таблиця перегортається. Щоб пейджер з'явився, повинен бути встановлений атрибут AllowPaging і кількість записів повинно бути більше PageSize. Всі ці властивості зручно встановлювати за допомогою PropertyBuilder.


У Visual Studio 2005 є можливість автоформатування, як і у DataList.


Новий варіант, без автоматичної генерації колонок і зі стилями.






 <asp:DataGrid ID="DataGrid2" runat="server" BackColor="#FFE0C0" ShowFooter="True" AutoGenerateColumns="False" PageSize="3">
    <AlternatingItemStyle BackColor=”#C0FFC0″ />
    <ItemStyle BackColor=”#FFFFC0″ />
<EditItemStyle BackColor="#C0C000" Font-Size="XX-Large" />
    <Columns>
<asp:BoundColumn DataField="name" FooterText="Name" HeaderText="Фамілія"> </ asp: BoundColumn>
<asp:BoundColumn DataField="nationality" FooterText="Country" HeaderText="Страна"> </ asp: BoundColumn>
<asp:BoundColumn DataField="winningdate" FooterText="Year won" HeaderText="Год"> </ asp: BoundColumn>
<asp:BoundColumn DataField="work" FooterText="Work" HeaderText="Проізведеніе"> </ asp: BoundColumn>
        </Columns>
<FooterStyle Font-Bold="True" Font-Italic="False" Font-Overline="False" Font-Strikeout="False" Font-Underline="False" />
<HeaderStyle Font-Bold="True" Font-Italic="False" Font-Overline="False" Font-Strikeout="False" Font-Underline="False" />
</asp:DataGrid>

Додамо в цю форму з можливістю сортування. DataGrid підтримує властивість AllowSorting. Але це лише потенційна можливість сортування, так як сам елемент сортувати не може, це має забезпечити програміст. При AllowSorting = True в заголовку виводяться гіперпосилання, при натисканні на які викликається подія SortCommand. Так як немає автогенерації, в опис BoundColumn потрібно вставити SortExpression.






 <asp:BoundColumn DataField="name" FooterText="Name" HeaderText="Фамілія" SortExpression="name">
    </asp:BoundColumn>

Метод-обробник події SortCommand приймає параметр типу DataGridSortCommandEventArgs, у властивості SortExpression якого міститься рядок – вираз сортування SortExpression. Необхідно використовувати це вираз для сортування даних, отриманих з джерела даних.






 protected void DataGrid2_SortCommand (object source, DataGridSortCommandEventArgs e)
{
    ViewState[“sort”] = e.SortExpression;
    bindData();
}

Де bindData () винесено в окрему функцію і викликається також з Page_Load.






  private void bindData()
{
    String xmlFilename = Server.MapPath(“”) + ”
obel.xml”;
    DataSet newDataSet = new DataSet();
    newDataSet.ReadXml(xmlFilename);
    if (ViewState[“sort”] != null)
newDataSet.Tables [3]. DefaultView.Sort = (string) ViewState ["sort"];
    DataTable newDataTable = newDataSet.Tables[3];
    DataGrid2.DataSource = newDataTable;
    DataGrid2.DataBind();
}
void Page_Load()
{
    if (!IsPostBack)
        bindData();
}


































Прізвище


Країна


Рік


Твір


Romain Rollan


France


1915


“Jean-Cristophe”


George Bernard Shaw


Great Britain


1925

 

Boris Pasternak


Russia


1958


“Doctor Zhivago”


Gabriel Garsia Marquez


Columbia


1982


“100 years of solitude”


Name


Country


Year won


Work


DataGrid підтримує можливість розбиття на сторінки, але для цього теж доводиться писати код обробників подій. У WebMatrix є шаблони таких сторінок. З появою GridView таку техніку можна вважати застарілою, оскільки GridView дозволяє робити все це за допомогою одного тільки декларативного зв'язування.


Покажемо можливість видалення, оновлення та редагування даних у DataGrid за допомогою SqlDataSource.


Створіть на сервері SQL у базі DemoBase таблицю Users з 3 полями:

























Column Name


Data Type


Allow Nulls


UID


int

 

Name


varchar(50)

 

Comments


varchar(250)

+


IsRegistered


bit

+


Поле UID – автоінкрементні. Тому операція INSERT не буде вимагати завдання його значення. Звичайно, це первинний ключ. У таблиці властивостей знайдіть IdentitySpecification, розкрийте його і виберіть (IsIdentity).


Будемо працювати з таблицею за допомогою 3 процедур.






  CREATE PROCEDURE dbo.SelectUsers
(
      @Col INT = 0
)
AS
IF @Col = 0
            SELECT * FROM Users
      ELSE IF @Col = 1
            SELECT * FROM Users ORDER BY NAME
      RETURN

Процедура EditUser буде використовуватися для вставки записів, якщо @ UID, і для оновлення в іншому випадку.






  CREATE PROCEDURE dbo.EditUser
      (
      @UID int = 0,
      @Name varchar(50),
      @Comments varchar(250),
      @Registered bit
)
AS
      IF @UID = 0
INSERT INTO Users (Name, Comments, IsRegistered) VALUES (@ Name, @ Comments, @ Registered)
      ELSE
UPDATE Users SET Name = @ Name, Comments = @ Comments, IsRegistered = @ Registered WHERE UID = @ UID
      RETURN

Процедура для видалення записів.






  CREATE dbo.DeleteUser
(
      @UID int
)
            AS
            DELETE FROM Users WHERE UID = @UID
      RETURN

На формі буде знаходитися, крім DataGrid, 2 елементи редагування NameTextBox і CommentTextBox і кнопка Add. Для наших таємних цілей додамо елемент керування типу HiddenField. Ця мета – зберігає id поточного елемента і передавати його SqlDataSource.


Додамо на форму таке джерело даних.






 <Asp: SqlDataSource ID = "SqlDataSource1" runat = "server"
ConnectionString ="<%$ ConnectionStrings: DemoBaseConnectionString%> "
SelectCommand = "dbo.SelectUsers" SelectCommandType = "StoredProcedure"
DeleteCommand = "dbo.DeleteUser" DeleteCommandType = "StoredProcedure"
UpdateCommand = "dbo.EditUser" UpdateCommandType = "StoredProcedure"
InsertCommand = "dbo.EditUser" InsertCommandType = "StoredProcedure"
    OldValuesParameterFormatString=””>
    <InsertParameters>
<Asp: Parameter Direction = "ReturnValue" Name = "RETURN_VALUE"
            Type=”Int32″ />
<asp:Parameter Name="UID" Type="Int32" DefaultValue="0" />
<asp:ControlParameter Name="Name" Type="String" ControlID="NameTextBox"/>
<asp:ControlParameter Name="Comments" Type="String" ControlID="CommentTextBox" PropertyName="Text"/>
<asp:ControlParameter Name="Registered" Type="Boolean" ControlID="Registered" PropertyName="Checked"/>
    </InsertParameters>
    <UpdateParameters>
<Asp: Parameter Direction = "ReturnValue" Name = "RETURN_VALUE"
          Type=”Int32″ />
<asp:ControlParameter Name="UID" Type="Int32" ControlID="HiddenField1" />
<asp:ControlParameter Name="Name" Type="String" ControlID="NameTextBox"/>
<asp:ControlParameter Name="Comments" Type="String" ControlID="CommentTextBox"/>
<asp:ControlParameter Name="Registered" Type="Boolean" ControlID="Registered" PropertyName="Checked"/>
    </UpdateParameters>
    <DeleteParameters>
        <asp:ControlParameter ControlID=”HiddenField1″
PropertyName=”Value” Name=”UID” Type=”Int32″ />
    </DeleteParameters>
</asp:SqlDataSource>

Зверніть увагу на те, що в InsertParameters значення параметра UID за умовчанням 0 і він не пов'язаний з елементом управління. В інших випадках він пов'язаний з HiddenField1. Значення в це поле буде передаватися в обробниках.


На цей раз DataGrid буде використовувати шаблонизировать стовпці TemplateColumn. Цей тип стовпця DataGrid дозволяє повністю управляти форматом відображення і редагування даних-можна виводити дані в кілька рядків або використовувати для редагування даних будь-які елементи управління. Наприклад, для відображення булевою інформації використовуємо елементи CheckBox.






  <asp:DataGrid id=”UsersDataGrid”  runat=”server”
    AutoGenerateColumns=”False” DataKeyField=”UID”
    OnDeleteCommand=”UsersDataGrid_DeleteCommand”
    OnUpdateCommand=”UsersDataGrid_UpdateCommand”
OnEditCommand = "UsersDataGrid_EditCommand" DataSourceID = "SqlDataSource1"
AllowSorting = "True" Caption = "Users" CaptionAlign = "Top">
    <Columns>
<asp:TemplateColumn HeaderText= "Імя">
      <ItemTemplate>
        <asp:Label id=”Label1″ runat=”server”
Text ="<%# DataBinder.Eval (Container, "DataItem.Name ")%>">
        </asp:Label>
      </ItemTemplate>
      <EditItemTemplate>
        <asp:TextBox id=NameTextBox runat=”server”
Text ="<%# DataBinder.Eval (Container, "DataItem.Name")%> ">
        </asp:TextBox>
      </EditItemTemplate>
    </asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Комментаріі">
      <ItemTemplate>
<Asp: Label id = "Label2" runat = "server" Text ="<%# DataBinder.Eval (Container, "DataItem.Comments ")%>"></ asp: Label>
      </ItemTemplate>
      <EditItemTemplate>
<Asp: TextBox id = CommentTextBox runat = "server" Text ="<%# DataBinder.Eval (Container, "DataItem.Comments ")%>">
        </asp:TextBox>
      </EditItemTemplate>
    </asp:TemplateColumn>
<asp:TemplateColumn HeaderText= "Зарегістрірован">
      <ItemTemplate>
<Asp: CheckBox runat = "server" ID = "Registered" Checked ="<%# (bool) DataBinder.Eval (Container, "DataItem.isRegistered")%> "
              Enabled=”False”></asp:CheckBox >
      </ItemTemplate>
      <EditItemTemplate>
<Asp: CheckBox runat = "server" ID = "Registered" Checked ="<%# (bool) DataBinder.Eval (Container, "DataItem.isRegistered") %>"></ asp: CheckBox>
      </EditItemTemplate>
      </asp:TemplateColumn>
    <asp:TemplateColumn>
      <ItemTemplate>
<asp:LinkButton id="LinkButton1" runat="server" CommandName="edit"> редагувати </ asp: LinkButton>::
<asp:LinkButton id="LinkButton2" runat="server" CommandName="delete"> видалити </ asp: LinkButton>
      </ItemTemplate>
      <EditItemTemplate>
<asp:LinkButton id="LinkButton3" runat="server" CommandName="update"> прийняти </ asp: LinkButton>::
<asp:LinkButton id="LinkButton4" runat="server" CommandName="cancel"> скасувати </ asp: LinkButton>
      </EditItemTemplate>
    </asp:TemplateColumn>
  </Columns>
</asp:DataGrid>

І інші елементи:






 <asp:TextBox ID="NameTextBox" runat="server"> </ asp: TextBox>
<asp:TextBox ID="CommentTextBox" runat="server"> </ asp: TextBox>
<asp:CheckBox ID="Registered" runat="server" /> <br /> <br />
<asp:Button ID="Button1" runat="server" Text="Add" OnClick="Add_Click" />
<asp:HiddenField ID=”HiddenField1″ runat=”server” />

DataGrid вже буде виводити дані, має гіперпосилання для редагування і видалення, але при натисненні нічого не відбувається. Залишається написати потрібний код. SqlDataSource вже знає параметри команди Delete, це єдиний параметр, і пов'язаний він був з HiddenField1. Потрібно записати значення ключа id в це поле.






 protected void UsersDataGrid_DeleteCommand (object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
HiddenField1.Value = UsersDataGrid.DataKeys [e.Item.ItemIndex]. ToString ();
/ / Видалення
    SqlDataSource1.Delete();
/ / Оновлення даних після видалення
    UsersDataGrid.DataBind();
}

Додавання запису відбувається ще простіше, оскільки параметри процедури Insert знаходяться в тих текстових полях, які заповнюються для вставки:






  protected void Add_Click(object sender, EventArgs e)
{
    SqlDataSource1.Insert();
    UsersDataGrid.DataBind();
}

У момент початку редагування текстові поля ховаються, так як значення з полів редагування усередині таблиці будуть копіюватися туди, і потрібно приховати це від користувача. Крім того, ці елементи управління під час редагування не потрібні.






 protected void UsersDataGrid_EditCommand (object source, DataGridCommandEventArgs e)
{
    UsersDataGrid.EditItemIndex = e.Item.ItemIndex;
    NameTextBox.Visible = false;
    CommentTextBox.Visible = false;
    Registered.Visible = false;
    UsersDataGrid.DataBind();
}

Редагування складніше. У шаблоні стовпців елемента DataGrid вказані текстові поля, які з'являються після нажанія на посилання «редагувати». Значення параметрів треба брати звідти, але їх не можна вказати в декларації SqlDataSource, тому що вони в момент генерації сторінки їх там просто немає. Наприклад, для того, щоб встановити в режим редагування рядок DataGrid, необхідно привласнити властивості EditItemIndex елемента управління DataGrid значення індексу поточного рядка.


У події UpdateCommand в аргументі e знаходимо поточний рядок. Оновлювані дані знаходяться в TextBox-ах в осередках 0 і 1. Щоб вийти з режиму редагування, властивості EditItemIndex потрібно присвоїти значення -1.






 protected void UsersDataGrid_UpdateCommand (object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
    TableCell cell=e.Item.Cells[0];
    TextBox cnt = (TextBox)cell.FindControl(“NameTextBox”);
    NameTextBox.Text = cnt.Text;
    cell = e.Item.Cells[1];
    cnt = (TextBox)cell.FindControl(“CommentTextBox”);
    CommentTextBox.Text = cnt.Text;
HiddenField1.Value = UsersDataGrid.DataKeys [e.Item.ItemIndex]. ToString ();
    cell = e.Item.Cells[2];
CheckBox check = (CheckBox) cell.FindControl ("Registered");
    Registered.Checked = check.Checked;
    SqlDataSource1.Update();
    UsersDataGrid.EditItemIndex = -1;
    UsersDataGrid.DataBind();
    NameTextBox.Text = “”;
    CommentTextBox.Text = “”;
    NameTextBox.Visible = true;
    CommentTextBox.Visible = true;
    Registered.Visible = true;
}

Після оновлення знову читаємо дані і робимо видимими поля редагування.


Відмова від редагування без збереження змін обробляється в події CancelCommand.






 protected void UsersDataGrid_CancelCommand (object source, DataGridCommandEventArgs e)
{
    UsersDataGrid.EditItemIndex = -1;
    NameTextBox.Visible = true;
    CommentTextBox.Visible = true;
    UsersDataGrid.DataBind();
}

Висновок


Ми розглянули 3 елементи управління, що існували з ASP.NET 1.0. Repeater використовує тільки шаблони, DataList створює таблицю і користується шаблоном для відображення її рядків, а DataGrid може обходитися і без шаблонів. Приблизно така ж система існує і у нових елементів управління ASP.NET 2.0.


Об'єктна модель спрощує зв'язування з даними, але її реальна влада реалізується при використанні нових елементів управління GridView, DetailsView, FormView, які ми розглянемо в наступній лекції.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*