Главная страница статей --> Хитрости при программировании php, заметки по базам данных

Обзор DetailsView

Источник: realcoding.net

Элемент управления DetailsView – одна из новинок ASP.NET 2.0. Он позволяет просматривать по одной записи из источника данных, тогда как GridView показывает их все сразу. Это можно сравнить с разными типами форм в Access: табличная форма соответствует GridView, а Columnar – DetailsView. Точно так же, как и GridView, DetailsView позволяет разбивку на страницы, редактирование, вставку и удаление с автоматическим связыванием с источником данных. Он также является наследником CompositeDataBoundControl.

Visual Studio 2005 предоставляет, как обычно, Smart Tag, с помощью которого можно задать источник данных, автоформатировать элемент управления, отредактировать поля и шаблоны полей.

Пример DetailsView, где данные берутся из базы данных Northwind, таблица Employees.

<asp:DetailsView ID=DetailsView1 runat=server AutoGenerateRows=False DataSourceID=SqlDataSource1
             
Height=50px Width=561px BackColor=White BorderColor=#DEDFDE BorderStyle=None BorderWidth=1px CellPadding=4 GridLines=Vertical ForeColor=Black AllowPaging=True>
              <
Fields>
                  <
asp:BoundField DataField=LastName HeaderText=LastName SortExpression=LastName />
                  <
asp:BoundField DataField=FirstName HeaderText=FirstName SortExpression=FirstName />
                  <
asp:BoundField DataField=Title HeaderText=Title SortExpression=Title />
                  <
asp:BoundField DataField=TitleOfCourtesy HeaderText=TitleOfCourtesy SortExpression=TitleOfCourtesy />
                  <
asp:BoundField DataField=BirthDate HeaderText=BirthDate SortExpression=BirthDate />
                  <
asp:BoundField DataField=HireDate HeaderText=HireDate SortExpression=HireDate />
                  <
asp:BoundField DataField=Address HeaderText=Address SortExpression=Address />
                  <
asp:BoundField DataField=City HeaderText=City SortExpression=City />
                  <
asp:BoundField DataField=Notes HeaderText=Notes SortExpression=Notes />
                  <
asp:BoundField DataField=HomePhone HeaderText=HomePhone SortExpression=HomePhone />
                  <
asp:BoundField DataField=Country HeaderText=Country SortExpression=Country />
                  <
asp:BoundField DataField=PostalCode HeaderText=PostalCode SortExpression=PostalCode />
                  <
asp:BoundField DataField=Region HeaderText=Region SortExpression=Region />
              </
Fields>
              <
FooterStyle BackColor=#CCCC99 />
              <
EditRowStyle BackColor=#CE5D5A Font-Bold=True ForeColor=White />
              <
RowStyle BackColor=#F7F7DE />
              <
PagerStyle BackColor=#F7F7DE ForeColor=Black HorizontalAlign=Right />
              <
HeaderStyle BackColor=#6B696B Font-Bold=True ForeColor=White />
              <
AlternatingRowStyle BackColor=White />
          </
asp:DetailsView>
  <
asp:SqlDataSource ID=SqlDataSource1 runat=server ConnectionString=<%$ ConnectionStrings:NorthwindConnectionString3 %>
             
SelectCommand=SELECT [LastName], [FirstName], [Title], [TitleOfCourtesy], [BirthDate], [HireDate], [Address], [City], [Extension], [ReportsTo], [Photo], [Notes], [HomePhone], [Country], [PostalCode], [Region] FROM [Employees] ProviderName=<%$ ConnectionStrings:NorthwindConnectionString3.ProviderName %>></asp:SqlDataSource>

А так это выглядит на форме:



Применялось автоформатирование Mocha.
Свойства пейджера такие же как у GridView. Единственное отличие – отсутствие свойства PageSize – так как DetailsView всегда отображает одну запись. Например, для навигации по страницам использовать картинки. При этом PagerSettings:Mode должен быть задан как NumericFirstLast.

<PagerSettings FirstPageImageUrl=~/RW_btn.gif LastPageImageUrl=~/FF_btn.gif Mode= NumericFirstLast
                  
NextPageImageUrl=~/fwd_btn.gif PreviousPageImageUrl=~/back_btn.gif />



Так гораздо красивее. Картинки взяты из поставки CorelDraw 11. Странно, что такой возможности не ввели в календаре, надеюсь в следующей версии появится.

Элементы коллекции полей BoundField описываются так же, как и в GridView, но текст заголовка появляется слева, а не сверху.
Совместное использование с GridView

Если в записи много полей, то на одной странице в GridView можно отобразить некоторые из них, а в DetailsView выводить полную информацию.

Чтобы это реализовать, нужны два SqlDataSource, которые подсоединяются к одной базе через тот же ConnectionString. Первый – обычный, читает все записи:

<asp:SqlDataSource ID=SqlDataSource1 runat=server 
      
ConnectionString=<%$ ConnectionStrings:NorthwindConnectionString %>
      
SelectCommand=SELECT * FROM [Employees] 
      
ProviderName=<%$ ConnectionStrings:NorthwindConnectionString.ProviderName %>>

Строка соединения определяется в Web.config:

<add name=NorthwindConnectionString connectionString=Data Source=.SQLExpress;Initial Catalog=Northwind;Integrated Security=True;Pooling=False


    
providerName=System.Data.SqlClient />

SqlDataSource1 связан с GridView, который поддерживает возможность выбора записи.

<asp:GridView ID=GridView1 runat=server AllowPaging=True AutoGenerateColumns=False CellPadding=4 DataSourceID=SqlDataSource1 ForeColor=#333333 GridLines=None AllowSorting=True PageSize=3 DataKeyNames=EmployeeID SelectedIndex=0>
      <
FooterStyle BackColor=#507CD1 Font-Bold=True ForeColor=White />
      <
RowStyle BackColor=#EFF3FB />
      <
SelectedRowStyle BackColor=#D1DDF1 Font-Bold=True ForeColor=#333333 />
      <
PagerStyle BackColor=#2461BF ForeColor=White HorizontalAlign=Center />
      <
HeaderStyle BackColor=#507CD1 Font-Bold=True ForeColor=White />
      <
AlternatingRowStyle BackColor=White />
      <
Columns>
      <
asp:CommandField ShowSelectButton=True />
      <
asp:BoundField DataField=LastName HeaderText=Фамилия SortExpression=LastName />
      <
asp:BoundField DataField=FirstName HeaderText=Имя SortExpression=FirstName />
       </
Columns>
       <
EditRowStyle BackColor=#2461BF />
  </
asp:GridView>

Если не указать SelectedIndex="0", то в начале не будет выбран ни одна запись и DetailsView на странице не появится.

Второй SqlDataSource фильтрует информацию по EmployeeID.

<asp:SqlDataSource ID=SqlDataSource2 runat=server 
      
SelectCommand=SELECT * FROM [Employees] WHERE ([EmployeeID]=@EmployeeID)
      
ConnectionString=<%$ ConnectionStrings:NorthwindConnectionString %> >
      <
SelectParameters>
      <
asp:ControlParameter ControlID=GridView1 Name=EmployeeID 
      
PropertyName=SelectedValue Type=String />
      </
SelectParameters
  </
asp:SqlDataSource>

Самое важное тут – SelectParameters. Таким образом в команду SelectCommand подставляется тот EmployeeID той записи, которая была выбрана в GridView1.

<asp:DetailsView ID=DetailsView1 runat=server 
      
DataSourceID=SqlDataSource2
      
Height=50px Width=561px
      
CellPadding=4 GridLines=None ForeColor=#333333 
      
HeaderText=Личное дело
      
AutoGenerateRows=False DataKeyNames=EmployeeID>
      <
Fields>
      <
asp:BoundField DataField=LastName HeaderText=Фамилия SortExpression=LastName />
      <
asp:BoundField DataField=FirstName HeaderText=Имя SortExpression=FirstName />
      <
asp:BoundField DataField=Title HeaderText=Должность SortExpression=Title />
      <
asp:BoundField DataField=BirthDate HeaderText=Дата рождения SortExpression=BirthDate />
      <
asp:BoundField DataField=HireDate HeaderText=Дата приема SortExpression=HireDate />
      <
asp:BoundField DataField=HomePhone HeaderText=Телефон SortExpression=HomePhone />
      </
Fields>
      <
FooterStyle BackColor=#507CD1 Font-Bold=True ForeColor=White />
      <
EditRowStyle BackColor=#2461BF />
      <
RowStyle BackColor=#EFF3FB />
      <
PagerStyle BackColor=#2461BF ForeColor=White HorizontalAlign=Center />
      <
HeaderStyle BackColor=#507CD1 Font-Bold=True ForeColor=White />
      <
AlternatingRowStyle BackColor=White />
      <
CommandRowStyle BackColor=#D1DDF1 Font-Bold=True />
      <
FieldHeaderStyle BackColor=#DEE8F5 Font-Bold=True />
  </
asp:DetailsView>



Вставка записей с помощью DetailsView

Чтобы наш DetailsView научился вставлять записи, необходимо установить свойство

AutoGenerateInsertButton="True". В элементе управления появляется кнопка “New”. Стоит ее нажать, и данные заменяются на TextBox-ы.

Но пока записи вставляться не будут. В SqlDataSource необходимо определить

1. Свойство InsertCommand
2. По одному InsertParameter Для каждого поля.

<asp:SqlDataSource ID=SqlDataSource2 runat=server 
      
SelectCommand=SELECT * FROM [Employees] WHERE ([EmployeeID]=@EmployeeID)
      
InsertCommand=INSERT INTO [Employees] ( [LastName],
      [FirstName], [Title], [BirthDate], [HireDate], [HomePhone])
           VALUES ( @LastName,
           @FirstName, @Title, @BirthDate, @HireDate, @HomePhone) 
      
ConnectionString=<%$ ConnectionStrings:NorthwindConnectionString %> >
      <
SelectParameters>
      <
asp:ControlParameter ControlID=GridView1 Name=EmployeeID 
      
PropertyName=SelectedValue
 
/>
      </
SelectParameters>
      <
InsertParameters>
      <
asp:Parameter Type=String Name=CustomerID></asp:Parameter>
      <
asp:Parameter Type=String Name=LastName></asp:Parameter>
      <
asp:Parameter Type=String Name=FirstName></asp:Parameter>
      <
asp:Parameter Type=String Name=Title></asp:Parameter>
      <
asp:Parameter Type=String Name=BirthDate></asp:Parameter>
      <
asp:Parameter Type=String Name=HireDate></asp:Parameter>
      <
asp:Parameter Type=String Name=HomePhone></asp:Parameter>
      </
InsertParameters>
  </
asp:SqlDataSource>

Ничего сложного, не так ли? :)

Можно также обновить вышестоящий GridView, чтобы в нем немедленно отображалась вставленная запись. Напишем обработчик события ItemInserted.

protected void DetailsView1_ItemInserted(object sender, DetailsViewInsertedEventArgs e)
      {
         
GridView1.DataBind();
      }

Работа с шаблонами полей.

Ввод дат было бы легче организовать с помощью календаря. Для этого можно определить шаблонизированное поле.

<asp:TemplateField HeaderText=Дата приема SortExpression=HireDate>
      <
EditItemTemplate>
      <
asp:TextBox ID=TextBox1 runat=server Text=<%# Bind(HireDate) %>></asp:TextBox>
      </
EditItemTemplate>
      <
InsertItemTemplate>
      <
asp:Calendar ID=CalendarHireDate runat=server 
      
BackColor=#EFF3FB ForeColor=#003399
      
SelectedDate=<%# Bind(HireDate) %>></asp:Calendar>
      </
InsertItemTemplate>
      <
ItemTemplate>
      <
asp:Label ID=Label1 runat=server Text=<%# Bind(HireDate) %>></asp:Label>
      </
ItemTemplate>
  </
asp:TemplateField>

И, конечно, нужно изменить тип параметров.

<asp:Parameter Type=DateTime Name=HireDate></asp:Parameter>

Редактирование и удаления делаются точно так, как в GridView.

Метод Bind, в отличие от метода Eval, работает в обе стороны, то есть не только читает данные из источника данных, но и позволяет его обновлять.

Возможность вставки записей DetailsView позволяет расширить возможности работы с источниками данных в ASP .NET 2.0.
События DetailsView

У DetailsView имеются пары событий, которые происходят при связывании с данными, при переходе из режима просмотра в режим вставки, при перелистывании страницы.

ItemCreated

ItemDeleting - ItemDeleted

ItemInserted - ItemInserting

ItemUpdated - ItemUpdating

ModeChanged - ModeChanging

В таблице Employees некоторые поля должны быть заполнены, у них стоит AllowNulls=false. Поэтому при работе нашей формы произойдет исключение, если попытаться вставить запись, не введя имя и фамилию. Чтобы избежать этого, во время обработки события ItemInserting нужно сделать проверку. Также обработаем событие ModeChanged, чтобы напомнить клиенту о его обязанностях. ))

protected void DetailsView1_ModeChanged(object sender, EventArgs e)
  {
      switch (
DetailsView1.CurrentMode)
      {
          case
DetailsViewMode.Insert:
             
DetailsView1.HeaderText = Заполните, пожалуйста, форму. Имя и фамилия обязательны.;
             
DetailsView1.HeaderStyle.ForeColor = System.Drawing.Color.Purple;
             
DetailsView1.HeaderStyle.BackColor = System.Drawing.Color.AliceBlue;
              break;
          case
DetailsViewMode.ReadOnly:
             
DetailsView1.HeaderText = Личное дело;
             
DetailsView1.HeaderStyle.ForeColor = System.Drawing.Color.White;
             
DetailsView1.HeaderStyle.BackColor = System.Drawing.Color.FromArgb(0x507CD1);
              break;
      }
  }



Так как DetailsView1 все-таки таблица, ищем поля ввода в 0 и 1 строке в 1 столбце. Если там пусто, отменим вставку.

protected void DetailsView1_ItemInserting(object sender, DetailsViewInsertEventArgs e)
      {
         
TextBox textbox1 = (TextBox)DetailsView1.Rows[0].Controls[1].Controls[0];
         
textbox1.Text.Trim();
         
TextBox textbox2 = (TextBox)DetailsView1.Rows[1].Controls[1].Controls[0];
         
textbox2.Text.Trim();
          if (
textbox1.Text == textbox2.Text == )
             
e.Cancel= true;
      }

Программное управление DetailsView

Предположим, мы нашли табличное представление информации о работнике слишком скучным. Мы хотим написать список характеристик работников в виде связного текста, а в DetailsView оставить только координаты(адрес, телефон).

Характеристика пишется с помощью элемента Repeater. Внутри него находится DetailsView. Источник данных рипитера– таблица Employees, как и выше. А какой установить источник у DetailsView? Если таким же, то для всех записей будет выводится та же самая информация – из первой записи таблицы. Так что для каждой записи нужен свой источник, отфильтрованный в соответствии с EmployeeID.

<asp:SqlDataSource ID=SqlDataSource1 runat=server ConnectionString=<%$ ConnectionStrings:NorthwindConnectionString1 %>
         
SelectCommand=SELECT * FROM [Employees] >
      </
asp:SqlDataSource>
      <
br>
      <
asp:Repeater ID=Repeater1 runat=server DataSourceID=SqlDataSource1 OnItemCreated=Repeater1_ItemCreated>
       <
ItemTemplate>
          <%
# DataBinder.Eval(Container.DataItem, TitleOfCourtesy) %>
         
<%# DataBinder.Eval(Container.DataItem, FirstName) %> 
         
<%# DataBinder.Eval(Container.DataItem, LastName) %> was born in 
         
<%# ((DateTime)DataBinder.Eval(Container.DataItem, BirthDate)).ToLongDateString() %>. <p>
         
<p>He/She lives in <%# DataBinder.Eval(Container.DataItem, City) %>
         
of the great country <%# DataBinder.Eval(Container.DataItem, Country) %>. </p>
         
<p>We appreciate her work as <%# DataBinder.Eval(Container.DataItem, Title) %>.</p>
         
<p><%# DataBinder.Eval(Container.DataItem, Notes) %></p>
         
<asp:DetailsView ID=DetailsView1 runat=server AutoGenerateRows=False DataKeyNames=EmployeeID
               
Height=50px Width=82%>
              <
Fields>
                  <
asp:BoundField DataField=Address HeaderText=Address SortExpression=Address />
                  <
asp:BoundField DataField=Region HeaderText=Region SortExpression=Region />
                  <
asp:BoundField DataField=PostalCode HeaderText=PostalCode SortExpression=PostalCode />
                  <
asp:BoundField DataField=HomePhone HeaderText=HomePhone SortExpression=HomePhone />
                  <
asp:BoundField DataField=Extension HeaderText=Extension SortExpression=Extension />
                  <
asp:ImageField HeaderText=Photo DataImageUrlField=PhotoPath>
                  </
asp:ImageField>
              </
Fields>
          </
asp:DetailsView>
          </
ItemTemplate>
          <
SeparatorTemplate><hr width=80dir=rtl></SeparatorTemplate>
      </
asp:Repeater>

Во время обработки события ItemCreated, когда данные еще не связаны, можно динамически связать DetailsView с данными.

protected void Repeater1_ItemCreated(object sender, RepeaterItemEventArgs e)
      {
          if (
e.Item.ItemType == ListItemType.Item e.Item.ItemType == ListItemType.AlternatingItem)
          {
             
SqlDataSource sds = new SqlDataSource();
             
sds.ConnectionString = SqlDataSource1.ConnectionString;
             
sds.ID = SqlDataSource2;
             
string Filter = String.Format(where EmployeeID = {0}, ((DataRowView)e.Item.DataItem)[EmployeeID]);
             
sds.SelectCommand = SELECT * FROM [Employees] + Filter;
             
e.Item.Controls.Add(sds);
             
System.Web.UI.WebControls.DetailsView ds = (System.Web.UI.WebControls.DetailsView)e.Item.FindControl(DetailsView1);
              if (
ds != null)
                  
ds.DataSourceID = sds.ID;
          }

Точно так же можно связать DetailsView с BulletedList, с DropDownList и другими.

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



Похожие статьи:
- Секреты правильной раскрутки сайтов
- Средства безопасности ASP.NET. Аутентификация
- Новое в ASP.NET 2. Профили пользователей
- Ожидание выполнения длительного процесса в ASP.NET
- Сайты доноры - источники траффика
- Роль контента в раскрутке сайта
- Лекция 6. Работа с базами данных.
- Лекция 4. Серверные элементы управления Продолжение.
- Шаблоны оформления
- ASP .NET 2.0: Эталонные страницы
- Будущее Web - за семантикой
- API-спецификация баз данных языка Python, версия 2.0
- Подготовка сайта к индексации


Оглавление | Обсудить на форуме | Главная страница сайта | Карта сайта |

Контакты
Редакция:
[0.002]