Я видел много одинаковых или похожих вопросов на форумах: Как разместить флажки, текстовые поля и т. д. в каждой строке DataGrid? Как обновить их значения? Ответ довольно прост, и в этой статье я покажу вам, как это сделать.
Мы все знаем, что DataGrid — очень мощный инструмент. По моему опыту, более 90% времени DataGrid используется для отображения данных и, возможно, редактирования их по одной строке за раз. Иногда вам может потребоваться отредактировать несколько строк или даже все данные одновременно. Практическим примером может служить приложение, которое продает товары через Интернет, где клиенты могут захотеть изменить один или несколько товаров в своей корзине одновременно, щелкнув флажки, чтобы удалить ненужные им товары.
Концепция
В этом примере я написал простую веб-форму для управления списком контактов, хранящимся в XML. Требование очень простое: иметь возможность добавлять новые контакты, редактировать/удалять существующие контакты. Пользователи могут изменять или удалять несколько контактов одновременно, а также я разрешаю пользователям сортировать сетку данных по столбцам по их выбору.
Мои примеры написаны на C#. Если вы предпочитаете версию этих кодов VB, код доступен в обоих форматах в загружаемом файле.
Файл данных XML в
примереContacts.xml
очень прост и интуитивно понятен.Поскольку это очень просто, я не составлял плана.
<?xml version="1.0" Standalone="да"?>
<Контакты>
<Контакт>
<Электронная почта>[email protected]</Email>
<Имя>Джон</Имя>
<LastName>Доу</LastName>
</Контакт>
<Контакт>
<Email>вашадрес@ваша компания.com</Email>
<Имя>Джейн</Имя>
<LastName>Доу</LastName>
</Контакт>
</Контакты>
ContactList.aspx
Настроить веб-форму очень просто. Я поместил в форму новый DataGrid и настроил в нем четыре столбца, причем первый столбец содержал флажки для удаления контактов. Вы заметите, что главное, что я здесь сделал, — это создал каждый столбец как столбец шаблона (TemplateColumn). Это позволяет мне размещать объекты текстового поля и флажка в шаблоне данных (ItemTemplate). Это трюк, позволяющий отображать в каждой строке сетки что-то кроме текста. Кроме того, вы заметите, что я использую FooterTemplate, чтобы сделать создание новых контактов простым и интуитивно понятным.
Я также включил LinkButton для сохранения изменений и удалений, сделанных пользователем. Но он не используется для добавления новых контактов. Завершает операцию добавления новых контактов кнопка ссылки (LinkButton) в шаблоне нижнего колонтитула последней колонки.
<asp:datagrid id="dgContacts" runat="server" ShowFooter="True" AllowSorting="True" Forefont color="Black" GridLines="None" CellPadding="2" Backfont color="LightGoldenrodYellow" BorderWidth="1px " Borderfont color="Tan" Width="499px" AutoGenerateColumns="False" DataKeyField="Email">
<SelectedItemStyle Forefont color="GhostWhite" Backfont color="DarkSlateBlue"></SelectedItemStyle>
<AlternatingItemStyle Backfont color="PaleGoldenrod"></AlternatingItemStyle>
<HeaderStyle Font-Bold="True" Backfont color="Tan"></HeaderStyle>
<FooterStyle Backfont color="Tan"></FooterStyle>
<Столбцы>
<asp:TemplateColumn SortExpression="FirstName" HeaderText="Имя">
<Шаблон элемента>
<asp:TextBox id=First runat="server" Width="109px" Text='<%# DataBinder.Eval(Container, "DataItem.FirstName") %>'>
</asp:TextBox>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox id="NewFirst" runat="server" Width="109px"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn SortExpression="LastName" HeaderText="Last Name">
<Шаблон элемента>
<asp:TextBox id=Last runat="server" Width="109px" Text='<%# DataBinder.Eval(Container, "DataItem.LastName") %>'>
</asp:TextBox>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox id="NewLast" runat="server" Width="109px"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn SortExpression="Электронная почта" HeaderText="Электронная почта">
<Шаблон элемента>
<asp:TextBox id=Email runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Email") %>'>
</asp:TextBox>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox id="NewEmail" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Удалить контакт">
<ItemStyle HorizontalAlign="Center"></ItemStyle>
<Шаблон элемента>
<asp:CheckBox Runat="server" ID="chkDelete"></asp:CheckBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Center"></FooterStyle>
<FooterTemplate>
<asp:LinkButton Runat="server" Text="Добавить" CommandName="Добавить" ID="Linkbutton1" NAME="Linkbutton1"></asp:LinkButton>
</FooterTemplate>
</asp:TemplateColumn>
</Колонки>
</asp:datagrid>
ContactList.cs
После того, как я решил использовать XML-файл для доступа к данным, я решил использовать для доступа к ним DataSet. Поскольку объект DataSet имеет методы ReadXml и WriteXml, это очень разумный выбор. Первым шагом является чтение данных в формате XML. Как вы можете видеть из кода, я создал элемент для сортировки данных.
частный набор данных _dsContacts;
частная строка _sSort
Private void Page_Load (отправитель объекта, System.EventArgs e)
{
//Загрузить XML-файл.
_dsContacts = новый DataSet();
_dsContacts.ReadXml(Server.MapPath("Contacts.xml"));
DataColumn[] dcPk = {_dsContacts.Tables["Контакт"].Columns["Электронная почта"]};
_dsContacts.Tables["Контакт"].PrimaryKey = dcPk;
if (!Page.IsPostBack)
{
// Если он загружается впервые, привязываем данные.
ПривязатьКонтакты();
_sSort = "Имя";
}
еще
{
// В противном случае читаем состояние сортировки из состояния просмотра.
_sSort = (строка)ViewState["Сортировка"];
}
}
На втором этапе я создал метод привязки данных к сетке, который включал в себя логику сортировки данных и методы чтения данных с диска.
частная пустота BindContacts()
{
//Сохраняем состояние сортировки для просмотра состояния.
ViewState["Sort"] = _sSort
// Привязываем сетку к представлению отсортированных данных.
DataView dv = новый DataView(_dsContacts.Tables["Контакт"]);
дв.Сорт = _sSort;
dgContacts.DataSource = дв;
dgContacts.DataBind();
}
частная пустота SaveContacts()
{
_dsContacts.WriteXml(Server.MapPath("Contacts.xml"));
}
Событие ItemCommand используется для обработки добавления новых контактов в список. Примечание. Я проверил, имеет ли параметр CommandName значение Add. Он предназначен для обработки возвращаемого значения кнопки ссылки (LinkButton) в шаблоне нижнего колонтитула (FooterTemplate) последнего столбца сетки на странице ASPX.
Private void dgContacts_ItemCommand (источник объекта, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
//Добавляем новые данные в набор данных. Здесь я использую массив для повышения эффективности обработки.
if (e.CommandName == "Добавить")
{
строка[] sContact = {"", "", ""};
sContact[0] = ((TextBox)e.Item.FindControl("NewEmail")).Text;
sContact[1] = ((TextBox)e.Item.FindControl("NewFirst")).Text;
sContact[2] = ((TextBox)e.Item.FindControl("NewLast")).Text;
_dsContacts.Tables["Contact"].Rows.Add(sContact
);
}
BindContacts();
}
Я пропустил код SortCommand, поскольку существует множество других документов, в которых сортировка обсуждается очень подробно. Если вы загрузите исходный код для этого примера, он будет включен.
Наконец, я переместил событие нажатия (onClick) кнопки ссылки (LinkButton) в форму сюда. Здесь я просматриваю элементы данных в DataGrid, чтобы выполнить все необходимые операции удаления и обновления.
Private void btnUpdate_Click (отправитель объекта, System.EventArgs e)
{
// Проходим по каждому элементу данных.
foreach (DataGridItem в dgContacts.Items)
{
// Убедитесь, что это элемент данных, а не верхняя или нижняя часть страницы.
if (di.ItemType == ListItemType.Item || di.ItemType == ListItemType.AlternatingItem)
{
// Получаем текущую строку после выполнения операции обновления или удаления.
DataRow dr = _dsContacts.Tables["Contact"].Rows.Find(dgContacts.DataKeys[di.ItemIndex]);
// Проверяем, нужно ли удалять строку.
if (((CheckBox)di.FindControl("chkDelete")).Проверено)
{
_dsContacts.Tables["Контакт"].Rows.Remove(dr);//Удалить указанную строку
}
еще
{
//Обновляем строку данных.
dr["Электронная почта"] = ((TextBox)di.FindControl("Электронная почта")).Text;
dr["FirstName"] = ((TextBox)di.FindControl("First")).Text;
dr["LastName"] = ((TextBox)di.FindControl("Last")).Text;
}
}
}
//Сохраняем, если есть изменения.
если (_dsContacts.HasChanges())
{
СохранитьКонтакты();
}
BindContacts();//Привязка
}
Заключение
Я могу легко найти ячейки (Cells) каждого DataGridItem в элементе управления по положению элемента управления. Есть несколько способов сделать это, и я уверен, что вы сможете найти лучший способ выполнить эту задачу. Как видите, редактировать сразу всю сетку данных очень просто. Тот же метод можно использовать и для сеток с разбивкой на страницы с небольшими изменениями.