Как сортировать столбцы в ASP.NET GridView при использовании собственного источника данных?

StackOverflow https://stackoverflow.com/questions/138412

Вопрос

Я не могу заставить свой 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, что значительно снижает нагрузку на страницу для сетевого трафика и для браузера.Это можно сделать, поскольку сетка полностью воссоздается каждый раз, когда страница возвращается.

Хорошего дня!

Мартин

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top