Как отсортировать столбцы в ASP.NET GridView при использовании пользовательского источника данных? - PullRequest
4 голосов
/ 26 сентября 2008

Я не могу заставить свой 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();

В настоящий момент ничего не происходит, когда пользователь нажимает на заголовок столбца, когда я ожидаю, что он отсортирует данные столбца. Кто-нибудь есть идеи, что мне не хватает?

Если есть более хороший способ сделать это, это было бы полезно, так как мне это кажется беспорядочным!

Ответы [ 4 ]

5 голосов
/ 13 декабря 2010

Вы также можете просто переназначить 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;
}

Надеюсь, это поможет. Дайте мне знать, если вам потребуется дополнительная помощь для его реализации.

Наслаждайтесь!

4 голосов
/ 26 сентября 2008

Сначала вам нужно добавить событие:

<asp:GridView AllowSorting="True" OnSorting="gvName_Sorting" ...

Тогда это событие выглядит так:

protected void gvName_Sorting( object sender, GridViewSortEventArgs e )
{
    ...
    //rebind gridview
}

В основном вам нужно снова получить данные.

Вы правы, что это выглядит грязно и есть лучший способ: ASP.Net MVC

К сожалению, это совершенно другая модель страницы.

0 голосов
/ 03 июня 2010

Лучше поздно, чем никогда?

Некоторое дополнение к предложению Кейта, которое в основном является правильным.

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

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

Martin

0 голосов
/ 26 сентября 2008

Я не уверен насчёт этого, но если вы используете стандартный SqlDataSource и щелкаете поле для сортировки по этому полю, SqlDataSource снова заполняется данными и возвращается к сетке. Таким образом, сортировка не происходит на стороне клиента, а также может быть выполнена только в том случае, если метод выбора объекта SQLDataSource не является DataReader.

При обработке события сортировки вы воссоздаете SqlDataSource и возвращаете его в GridView? Можете ли вы поместить поле сортировки и направление в генерируемую команду выбора, которую вы используете? Или поместите его в свойство SortParameterName объекта SQLDataSource?

Я абсолютно уверен, что вам нужно привязать SqlDataSource к сетке, и, поскольку вы создаете его на лету, вы должны заполнить его снова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...