Исходники.Ру - Программирование
Исходники
Статьи
Книги и учебники
Скрипты
Новости RSS
Магазин программиста

Главная » Статьи по программированию » .NET - Все статьи »

Обсудить на форуме Обсудить на форуме

Редактирование данных в DataGrid

В элемент управления DataGrid (как впрочем и в DataList) встроена мощная поддержка возможности редактирования связанных с этим элементом данных. Оба этих элемента управления позволяют управлять отображением выбранной или редактируемой записи, а также обновлять связанные данные. И все это при минимальном программировании. Например, для того, чтобы установить в режим редактирования пятую строку DataGrid необходимо присвоить свойству EditItemIndex элемента управления DataGrid значение 4 (нумерация строк в DataGrid начинается с 0). Соответственно для того, чтобы выйти из режима редактирования необходимо свойству EditItemIndex присвоить значение -1. Наиболее сложной операцией при редактировании DataGrid является извлечение введенных данных и запись их в источник данных, но эта операция сложна только по сравнению с прочими простейшими операциями редактирования. Впрочем вскоре мы в этом убедимся.

Для генерации событий редактирования, отмены редактирования и сохранения редактирования (EditCommand, CancelCommand и UpdateCommand соответственно) в DataGrid предусмотрен специальный тип столбца – ButtonColumn. Он генерит кнопки редактирования, сохранения и отмены редактирования, нажатие которых вызsdftn соответствующие события в DataGrid. Вооружившись этими данными попробуем создать простейший DataGrid с возможностью редактирования. Создадим DataGrid с автоматической генерацией столбцов и добавим к нему столбец типа ButtonColumn.

<%@ Page language="c#" Src="DataGridEdit1.aspx.cs" %>
 <HTML>
 <HEAD>
  <title>DataGridEdit1</title>
 </HEAD>
 <body>
  <form id="DataGridEdit1" method="post" runat="server">
   <asp:DataGrid id="DataGrid1" runat="server" AutoGenerateColumns=”True”>
    <Columns>
     <asp:EditCommandColumn ButtonType="LinkButton" UpdateText="Сохранить" CancelText="Отменить" EditText="Редактировать">
     </asp:EditCommandColumn>
    </Columns>
   </asp:DataGrid>
  </form>
 </body>
</HTML>
 

Теперь необходимо связать DataGrid с данными из источника данных (в данном случае это будут данные из таблицы Authors базы pubs) и обработать события редактирования для DataGrid.

Для связывания данных применяется следующий метод:

private void bindData()
{
  SqlConnection myConn = new SqlConnection("server=localhost;uid=sa;pwd=;database=pubs");
  SqlDataAdapter myData = new SqlDataAdapter("select au_id, au_fname, au_lname, state, contract from authors", myConn);
  DataSet ds = new DataSet();
  myData.Fill(ds);
  DataGrid1.DataSource = ds.Tables[0].DefaultView;
  DataGrid1.DataKeyField = "au_id";
  DataGrid1.DataBind();
}
 

Этот метод получает данные из источника данных и связывает их с элементом DataGrid. Кроме этого устанавливается значение свойства DataKeyField (нужно же будет как-то искать потом редактируемую строку в наборе данных). Обработчики событий редактирования и отмены редактирования просты до невозможности. Все, что в них происходит, это устанавливается значение свойства EditItemIndex элемента DataGrid и вызывается метод bindData():

private void DataGrid1_EditCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
  DataGrid1.EditItemIndex = e.Item.ItemIndex;
  bindData();
}
private void DataGrid1_CancelCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
  DataGrid1.EditItemIndex = -1;
  bindData();
}
 

Наиболее сложным (и интересным) является метод – обработчик события сохранения данных. Перед тем, как представить его код, рассмотрим как DataGrid создает элементы при связывании данных.

В момент связывания данных в BoundColumn (а именно эти столбцы применяются при установке AutoGeneratedColumn=”true” для DataGrid) в ячейку генерируемой таблицы для каждого поля вставляется либо LiteralControl с данными из соответствующего поля источника данных, либо же (только для редактируемой строки) элемент TextBox, значению свойства Text которого присваивается значение данных из соответствующего поля. Исходя из вышесказанного данные, которые необходимо сохранить, находятся в элементах TextBox, которые в свою очередь являются первыми (и единственными) элементами управления в соответствующих ячейках.

private void DataGrid1_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
  SqlConnection myConn = new SqlConnection("server=localhost;uid=sa;pwd=;database=pubs");
  SqlDataAdapter myData = new SqlDataAdapter("select au_id, au_fname, au_lname, state, contract from authors", myConn);
  DataSet ds = new DataSet();
  myData.Fill(ds);
  ds.Tables[0].PrimaryKey = new DataColumn[] {ds.Tables[0].Columns["au_id"]};
  DataRow dr = ds.Tables[0].Rows.Find(DataGrid1.DataKeys[e.Item.ItemIndex]);
  if(dr != null)
  {
    dr["au_fname"] = ((TextBox)e.Item.Cells[2].Controls[0]).Text;
    dr["au_lname"] = ((TextBox)e.Item.Cells[3].Controls[0]).Text;
    dr["state"] = ((TextBox)e.Item.Cells[4].Controls[0]).Text;
    dr["contract"] = Boolean.Parse(((TextBox)e.Item.Cells[5].Controls[0]).Text);
  }
  ds.AcceptChanges();
  DataGrid1.EditItemIndex = -1;
  DataGrid1.DataSource = ds.Tables[0].DefaultView;
  DataGrid1.DataKeyField = "au_id";
  DataGrid1.DataBind();
}
 

Как видите ничего экстраординарного в данном методе нет. Сначала метод ищет редактируемую строку. Затем в поля этой строки записываются введенные данные. И, наконец, изменения сохраняются и данные связываются с DataGrid.

В данном примере не происходит реального изменения данных в источнике данных – меняются только данные в DataSet. Но ничего не стоит изменить приведенный выше метод и добавить также код записи изменений в базу данных.

В приведенном выше примере при редактировании строки выводятся элементы управления TextBox для всех полей, в том числе и для поля au_id, представляющего собой первичный ключ таблицы authors. Данные полей с первичным ключом обычно не редактируются дабы не нарушить целостность данных. Поэтому хорошо было бы убрать возможность редактирования данных в поле au_id. Это сделать очень просто – установив свойство ReadOnly второго столбца DataGrid в true. К сожалению элемент управления DataGrid не предоставляет доступ к списку автоматически генерируемых столбцов, так что придется сначала также описать все столбцы в DataGrid и убрать AutoGeneratedColumns=true. Вот как будет выглядеть необходимое описание столбцов в DataGrid:

<asp:EditCommandColumn ButtonType="LinkButton" UpdateText="Сохранить" CancelText="Отменить" EditText="Редактировать"></asp:EditCommandColumn>
<asp:BoundColumn DataField="au_id" ReadOnly="True" HeaderText="ID"></asp:BoundColumn>
<asp:BoundColumn DataField="au_fname" HeaderText="First Name"></asp:BoundColumn>
<asp:BoundColumn DataField="au_lname" HeaderText="Last Name"></asp:BoundColumn>
<asp:BoundColumn DataField="state" HeaderText="State"></asp:BoundColumn>
<asp:BoundColumn DataField="contract" HeaderText="Contract"></asp:BoundColumn>
 

Остальной код предыдущего примера остается без изменений. Теперь при редактировании строки поле au_id недоступно для изменений.

Столбцы типа BoundColumn и их использование для отображения и редактирования данных в DataGrid очень простое и, вместе с тем, достаточно мощное средство. Но как быть если для редактирования данных в DataGrid необходимо использовать элементы управления, отличные от поля ввода (например выпадающий список или флажок)? В этом случае на помощь приходят столбцы шаблонов (TemplateColumn). Данный тип столбца DataGrid позволяет полностью управлять форматом отображения и редактирования данных – вы можете выводить данные в несколько строк или использовать для редактирования данных любые элементы управления. Но при редактировании данных, описанных с помощью TemplateColumn возникают свои тонкости. Их то мы сейчас и рассмотрим.

Рассмотрим все тот же пример с данными из таблицы authors базы pubs. Только теперь все столбцы в DataGrid описаны как TemplatedColumn:

<asp:EditCommandColumn ButtonType="LinkButton" UpdateText="Сохранить" CancelText="Отменить" EditText="Редактировать">
</asp:EditCommandColumn>
<asp:BoundColumn DataField="au_id" ReadOnly="True" HeaderText="ID"></asp:BoundColumn>
<asp:TemplateColumn HeaderText="First Name">
 <ItemTemplate>
  <%# DataBinder.Eval(Container, "DataItem.au_fname") %>
 </ItemTemplate>
 <EditItemTemplate>
  <asp:TextBox id="fname" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.au_fname") %>'>
  </asp:TextBox>
 </EditItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Last Name">
 <ItemTemplate>
  <%# DataBinder.Eval(Container, "DataItem.au_lname") %>
 </ItemTemplate>
 <EditItemTemplate>
  <asp:TextBox ID="lname" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.au_lname") %>'>
  </asp:TextBox>
 </EditItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="State">
 <ItemTemplate>
  <%# DataBinder.Eval(Container, "DataItem.state") %>
 </ItemTemplate>
 <EditItemTemplate>
 <asp:DropDownList ID="state" Runat="server">
 <asp:ListItem Value="">Select</asp:ListItem>
 <asp:ListItem Value="CA">California</asp:ListItem>
 <asp:ListItem Value="UT">Utah</asp:ListItem>
 <asp:ListItem Value="TN">Tennessee</asp:ListItem>
 <asp:ListItem Value="OR">Oregon</asp:ListItem>
 <asp:ListItem Value="MI">Michigan</asp:ListItem>
 <asp:ListItem Value="IN">Indiana</asp:ListItem>
 <asp:ListItem Value="MD">Maryland</asp:ListItem>
 </asp:DropDownList>
 </EditItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Contract">
 <ItemTemplate>
  <%# DataBinder.Eval(Container, "DataItem.contract") %>
 </ItemTemplate>
 <EditItemTemplate>
 <asp:CheckBox ID="contract" Runat="server" Checked='<%# (bool) DataBinder.Eval(Container, "DataItem.contract") %>' />
 </EditItemTemplate>
</asp:TemplateColumn>
 

Все редактируемые колонки в DataGrid теперь описаны как TemplateColumn. Также изменены элементы редактирования данных – теперь штат автора нужно выбирать из выпадающего списка, а контракт с автором устанавливается с помощью флажка. Также теперь все элементы редактирования данных проименованы.

Теперь необходимо также изменить обработчик события UpdateCommand, так как код предыдущих примеров теперь работать не будет. Изменению подлежит только часть кода, связанная с получением данных из элементов редактирования, остальной код остается неизменным:

dr["au_fname"] = ((TextBox) e.Item.Cells[2].Controls[1]).Text;
dr["au_lname"] = ((TextBox) e.Item.FindControl("lname")).Text;
dr["state"] = ((DropDownList) e.Item.FindControl("state")).SelectedItem.Value;
dr["contract"] = ((CheckBox) e.Item.FindControl("contract")).Checked;
 

В приведенном выше коде показаны 2 способа получения данных из элементов редактирования при использовании столбцов типа TemplateColumn. Первый тип – уже знакомый нам доступ к элементу редактирования через список Controls соответствующей ячейки. Обратите внимание, что индекс элемента в списке теперь уже не 0, а 1, т.е. элемент редактирования является вторым в списке элементов ячейки. Это происходит потому, что при отображении данных в TemplateColumn ASP.NET воспринимает весь текст, заключенный в теге как шаблон. И при этом обрабатывается также пространство до и после элемента редактирования (в нашем случае пробелы и переводы строк обрабатывается как LiteralContol).

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

Как видите возможность редактирования данных в элементе управления DataGrid дает очень многое. Используя ее вы можете быстро отображать данные из источников данных и иметь полнофункциональную возможность редактирования этих данных.


Текст примеров данной статьи можно выкачать здесь


Может пригодится:


Автор: Manowar
Прочитано: 9123
Рейтинг:
Оценить: 1 2 3 4 5

Комментарии: (0)

Добавить комментарий
Ваше имя*:
Ваш email:
URL Вашего сайта:
Ваш комментарий*:
Код безопастности*:

Рассылка новостей
Рейтинги
© 2007, Программирование Исходники.Ру