|
Достаточно простой вопрос сортировки данных в DataGrid, неплохо освещенный в тех же квикстартах, оказывается все таки вызывает вопросы его реализации у начинающих ASP.NET программистов. Что в итоге и послужило поводом написания этой статьи.
Что же может предложить элемент DataGrid для помощи в сортировке данных?
В элемент DataGrid встроена возможность сортировки данных. Но именно возможность, т.е. реально DataGrid не может сам сортировать встроенные в него данные. Да и как он мог бы это делать, если все, что ему нужно для вывода данных, это объект, реализующий интерфейсы IEnumerable. Фактически все, что делает установка свойства AllowSorting элемента DataGrid в true, это вывод заголовков столбцов в виде кнопок, при нажатии на которые вызывается событие SortCommand. А как его обрабатывать да как при этом сортировать данные в DataGrid – это уже забота программиста.
Рассмотрим простейший пример сортировки данных в DataGrid. На веб форме расположен элемент DataGrid со свойствами AutoGenerateColumn и AllowSorting установленными в true.
<asp:DataGrid id="DataGrid1" runat="server" AllowSorting="True" AutoGenerateColumns=”True”>
</asp:DataGrid>
Для связывания данных из источника данных используется вспомогательный метод bindData(), который заполняет DataSet данными и затем связывает полученный DataSet и DataGrid:
private void bindData()
{
SqlConnection myConn = new SqlConnection("server=localhost;uid=sa;pwd=;database=pubs");
SqlDataAdapter myData = new SqlDataAdapter("select * from authors", myConn);
DataSet ds = new DataSet();
myData.Fill(ds);
DataGrid1.DataSource = ds.Tables[0].DefaultView;
DataGrid1.DataBind();
}
Вызывается этот метод в обработчике события Load страницы:
private void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostBack)
bindData();
}
Подготовительная работа произведена, теперь пора и реализовать сортировку. Для этого необходимо обработать событие SortCommand элемента DataGrid И внести небольшие изменения в метод bindData(). Метод-обработчик события Sortcommand принимает параметр типа DataGridSortCommandEventArgs, в свойстве SortExpression которого содержится строка – выражение сортировки. И все, что необходимо сделать – использовать это выражение для сортировки данных, полученных из источника данных.
В примере передаваемое значение SortExpression сохраняется в ViewState для дальнейшего использования и после этого вызывается метод bindData() для связывания данных:
private void DataGrid1_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
{
ViewState["sort"] = e.SortExpression;
bindData();
}
Для того, чтобы использовать значение сортировки для реальной сортировки данных в методе bindData() после вызова myData.Fill(ds) необходимо вставить следующие строки:
if(ViewState["sort"] != null)
ds.Tables[0].DefaultView.Sort = (string) ViewState["sort"];
Все. Работа по сортировке данных в DataGrid выполнена.
Использование автоматической генерации столбцов не раскрывает всей мощности возможностей сортировки в DataGrid. Для того, чтобы несколько расширить наши знания в этом рассмотрим следующий пример, в котором элемент DataGrid будет иметь описанные столбцы различных типов.
<asp:DataGrid id="DataGrid1" runat="server" AllowSorting="True" AutoGenerateColumns="False">
<Columns>
<asp:TemplateColumn SortExpression="au_lname, au_fname" HeaderText="Last Name">
<ItemTemplate>
<asp:Label runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.au_lname") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn SortExpression="au_lname, au_fname" HeaderText="First Name">
<ItemTemplate>
<asp:Label runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.au_fname") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
<asp:HyperLinkColumn DataTextField="phone" SortExpression="phone" HeaderText="Phone" NavigateUrl="#"></asp:HyperLinkColumn>
<asp:BoundColumn DataField="address" HeaderText="Address"></asp:BoundColumn>
<asp:BoundColumn DataField="city" SortExpression="state, city desc" HeaderText="City"></asp:BoundColumn>
<asp:ButtonColumn Text="X" ButtonType="PushButton" SortExpression="contract desc" HeaderText="Fiction"></asp:ButtonColumn> </Columns>
</asp:DataGrid>
Классы столбцов элемента DataGrid являются наследниками абстрактного класса DataGridColumn, который в свою очередь имеет свойство SortExpression, определяющее выражение сортировки для столбца. Соответственно возможность сортировки можно использовать для столбца любого типа – необходимо только установить соответствующие значения для свойства SortExpression. Выражением сортировки может быть любое правильное с точки зрения языка SQL выражение для ORDER BY. В приведенном выше примере используются столбцы всех четырех типов для элемента DataGrid (в том числе и столбец типа ButtonColumn, для него, как ни странно, тоже можно устанавливать выражение сортировки). При этом изменилось только описание столбцов в DataGrid, весь код остался для этого примера неизменным.
Свойство SortExpression можно изменять в режиме выполнения. Соответственно данную возможность можно использовать для создания двунаправленной сортировки в DataGrid (эх, сколько приходилось мучаться для реализации подобной функциональности в asp :)). Все, что для этого нужно – небольшая дополнительная обработка свойств SortExpression в обработчике события SortCommand. В этом примере будет использоваться DataGrid со следующим описанием столбцов:
<asp:BoundColumn DataField="au_id" SortExpression="au_id" HeaderText="ID"></asp:BoundColumn>
<asp:BoundColumn DataField="au_lname" SortExpression="au_lname" HeaderText="Last Name"></asp:BoundColumn>
<asp:BoundColumn DataField="au_fname" SortExpression="au_fname" HeaderText="First Name"></asp:BoundColumn>
<asp:BoundColumn DataField="phone" SortExpression="phone" HeaderText="Phone"></asp:BoundColumn>
<asp:BoundColumn DataField="address" SortExpression="address" HeaderText="Address"></asp:BoundColumn>
<asp:BoundColumn DataField="city" SortExpression="city" HeaderText="City"></asp:BoundColumn>
<asp:BoundColumn DataField="state" SortExpression="state" HeaderText="State"></asp:BoundColumn>
<asp:BoundColumn DataField="zip" SortExpression="zip" HeaderText="Zip"></asp:BoundColumn>
<asp:BoundColumn DataField="contract" SortExpression="contract" HeaderText="Contract"></asp:BoundColumn>
В обработчике события SortCommand после сохранения выражения сортировки необходимо пройтись по всем столбцам DataGrid, найти текущий столбец (столбец, у которого свойство SortExpression равно выражению, переданному в обработчик) и поменять направление сортировки для этого столбца (добавить или удалить строку " desc". Также в коде в заголовок столбца добавляются символы, указывающие текущее направление сортировки. Весь код обработчика SortCommand представлен ниже:
private void DataGrid1_SortCommand(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
{
ViewState["sort"] = e.SortExpression;
foreach(DataGridColumn column in DataGrid1.Columns)
{
column.HeaderText = column.HeaderText.Replace(" v", "");
column.HeaderText = column.HeaderText.Replace(" ^", "");
if(column.SortExpression == e.SortExpression)
{
if(e.SortExpression.IndexOf(" desc") != -1)
{
column.SortExpression = column.SortExpression.Replace(" desc", "");
column.HeaderText += " ^";
}
else
{
column.SortExpression += " desc";
column.HeaderText += " v";
}
}
}
bindData();
}
Ничего сложного, не так ли? :)
Возможность сортировки, имеющаяся в элементе управления DataGrid, представляет собой простое, но вместе с тем и мощное средство сортировки данных. С помощью данной функциональности ваши данные будут иметь еще более удобный вид для пользователей. И все это при минимальных затратах. |