Как сортировать столбцы в ASP.NET GridView при использовании собственного источника данных?
-
02-07-2019 - |
Вопрос
Я не могу заставить свой GridView позволить пользователю сортировать столбец данных, когда я использую собственный SqlDataSource.
У меня есть GridView, в котором код в ссылке ASP на него в HTML минимален:
<asp:GridView id="grid" runat="server" AutoGenerateColumns="False" AllowSorting="True">
</asp:GridView>
В коде программной части я присоединяю динамически созданный SqlDataSource (столбцы, которые он содержит, не всегда одинаковы, поэтому SQL, используемый для его создания, создается во время выполнения).Например:
Я установил колонки...
BoundField column = new BoundField();
column.DataField = columnName;
column.HeaderText = "Heading";
column.SortExpression = columnName;
grid.Columns.Add(column);
источник данных...
SqlDataSource dataSource = new SqlDataSource(
"System.Data.SqlClient",
connectionString,
generatedSelectCommand);
затем сетка...
grid.DataSource = dataSource;
grid.DataKeyNames = mylistOfKeys;
grid.DataBind();
На данный момент ничего не происходит, когда пользователь нажимает на заголовок столбца, хотя я ожидал, что он отсортирует данные столбца.У кого-нибудь есть идеи, чего мне не хватает?
Если есть более приятный способ сделать это, это тоже было бы полезно, поскольку мне это кажется беспорядочным!
Решение
Сначала вам нужно добавить событие:
<asp:GridView AllowSorting="True" OnSorting="gvName_Sorting" ...
Тогда это событие выглядит так:
protected void gvName_Sorting( object sender, GridViewSortEventArgs e )
{
...
//rebind gridview
}
По сути, вам придется снова получить свои данные.
Вы правы, это выглядит грязно, и есть лучший способ:ASP.Net MVC
К сожалению, это совершенно другая модель страницы.
Другие советы
Вы также можете просто переназначить datasource.SelectCommand перед вызовом DataBind() в обработчике сортировки.Что-то вроде этого:
protected void gvItems_Sorting(object sender, GridViewSortEventArgs e)
{
GridView gv = (GridView)sender;
SqlDataSource ds = (SqlDataSource)gv.DataSource;
ds.SelectCommand = ds.SelectCommand + " order by "
+ e.SortExpression + " " + GetSortDirection(e.SortDirection);
gvItems.DataSource = ds;
gvItems.DataBind();
}
string GetSortDirection(string sSortDirCmd)
{
string sSortDir;
if ((SortDirection.Ascending == sSortDirCmd))
{
sSortDir = "asc";
}
else
{
sSortDir = "desc";
}
return sSortDir;
}
Я надеюсь, что это поможет.Дайте мне знать, если вам нужна дополнительная помощь для его реализации.
Наслаждаться!
Я не уверен насчет этого, но если вы используете стандартный SqlDataSource и щелкаете поле для сортировки по этому полю, SqlDataSource снова заполняется данными и повторно привязывается к сетке.Таким образом, сортировка не происходит на стороне клиента, а также может быть выполнена только в том случае, если метод выбора SQLDataSource не является DataReader.
При обработке события сортировки вы воссоздаете SqlDataSource и повторно привязываете его к GridView?Можете ли вы поместить поле сортировки и направление в созданную вами SelectCommand, которую вы используете?Или поместить его в свойство SortParameterName SQLDataSource?
Я абсолютно уверен, что вам придется заново привязывать SqlDataSource к сетке, а так как вы создаете его на лету, то и заполнять его придется заново.
Лучше поздно, чем никогда?
Некоторое дополнение к предложению Кита, которое в принципе правильное.
Правда в том, что вам придется иметь дело с сортировкой по событию GridView_Sorting.Нет необходимости использовать DataBind() для GridView ранее, например, в событии Page_Load.Там вам следует вызывать только метод GridView.Sort() вместо .DataBind().Вот как это происходит:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Me.gridView.Sort(Request.QueryString("sortExpression"), Request.QueryString("sortDirection"))
End If
End Sub
Далее давайте посмотрим на событиеgridView_Sorting.
Там вам нужно подтолкнуть источник данных к правильной сортировке.Сам GridView с этим не справляется (по крайней мере, в этом случае).
Protected Sub gridView_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles gridView.Sorting
If IsPostBack Then
e.Cancel = True
Dim sortDir As SortDirection = SortDirection.Ascending
If e.SortExpression = Me.Q_SortExpression And Me.Q_SortDirection = SortDirection.Ascending Then
sortDir = SortDirection.Descending
End If
RedirectMe(e.SortExpression, sortDir)
Else
Dim sortExpr As String = e.SortExpression + " " + IIf(e.SortDirection = SortDirection.Ascending, "ASC", "DESC")
Dim dv As System.Data.DataView = Me.dsrcView.Select(New DataSourceSelectArguments(sortExpr))
Me.gridView.DataSource = dv
Me.gridView.DataBind()
End If
End Sub
Нет необходимости кодировать какие-либо функции сортировки в источнике данных, например передачу параметров сортировки в хранимую процедуру.Вся сортировка происходит в приведенных выше фрагментах кода.
Более того, хорошо, если для GridView.EnableViewState установлено значение False, что значительно снижает нагрузку на страницу для сетевого трафика и для браузера.Это можно сделать, поскольку сетка полностью воссоздается каждый раз, когда страница возвращается.
Хорошего дня!
Мартин