Сортировка и разбиение по страницам с gridview asp.net

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

Проблема в том, что когда пользователь щелкает столбец, который он хочет отсортировать, он сортирует эту страницу, но не сортирует источник данных (представление данных) за сеткой. Поэтому, когда они переходят на другую страницу, их вид теряется. В значительной степени я ищу вид, который на самом деле отсортирует источник данных за сеткой. Вот что у меня так далеко:

protected void GridView_OnSort(object sender, GridViewSortEventArgs e)
    {
        String sortExpression = e.SortExpression;

        if (GridViewSortDirection == SortDirection.Ascending)
        {
            DataView myDataView = new DataView(mybll.GetItemsOrdered());
            myDataView.Sort = sortExpression + " DESC";
            GridView.DataSource = myDataView;
            GridView.DataBind();
        }
        else
        {
            DataView myDataView = new DataView(mybll.GetItemsOrdered());
            myDataView.Sort = sortExpression + " ASC";
            GridView.DataSource = myDataView;
            GridView.DataBind();
        }
    }

Любая помощь будет оценена. Благодарю.

5 ответов

Решение

Сохраните порядок сортировки в ViewState.

private const string ASCENDING = " ASC";
private const string DESCENDING = " DESC";

public SortDirection GridViewSortDirection
{
    get
    {
        if (ViewState["sortDirection"] == null)
            ViewState["sortDirection"] = SortDirection.Ascending;

        return (SortDirection) ViewState["sortDirection"];                
    }
    set { ViewState["sortDirection"] = value; } 
}

protected void GridView_Sorting(object sender, GridViewSortEventArgs e)
{
    string sortExpression = e.SortExpression;

    if (GridViewSortDirection == SortDirection.Ascending)
    {
        GridViewSortDirection = SortDirection.Descending;
        SortGridView(sortExpression, DESCENDING);
    }
    else
    {
        GridViewSortDirection = SortDirection.Ascending;
        SortGridView(sortExpression, ASCENDING); 
    }   

}

private void SortGridView(string sortExpression,string direction)
{
    //  You can cache the DataTable for improving performance
    DataTable dt = GetData().Tables[0]; 

    DataView dv = new DataView(dt); 
    dv.Sort = sortExpression + direction;         

    GridView1.DataSource = dv;
    GridView1.DataBind();         
}

Почему вы не хотите использовать существующие функции сортировки? Вы всегда можете настроить его.

Сортировка данных в элементе управления веб-сервера GridView на MSDN

Вот пример с настройкой:

http://www.netomatix.com/development/GridViewSorting.aspx

<asp:GridView 
    ID="GridView1" runat="server" AutoGenerateColumns="false" AllowSorting="True" onsorting="GridView1_Sorting" EnableViewState="true"> 
    <Columns>
        <asp:BoundField DataField="bookid" HeaderText="BOOK ID"SortExpression="bookid"  />
        <asp:BoundField DataField="bookname" HeaderText="BOOK NAME" />
        <asp:BoundField DataField="writer" HeaderText="WRITER" />
        <asp:BoundField DataField="totalbook" HeaderText="TOTALBOOK" SortExpression="totalbook"  />
        <asp:BoundField DataField="availablebook" HeaderText="AVAILABLE BOOK" />
    </Columns>
</asp:GridView>

Код позади:

protected void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack) {
            string query = "SELECT * FROM book";
            DataTable DT = new DataTable();
            SqlDataAdapter DA = new SqlDataAdapter(query, sqlCon);
            DA.Fill(DT);

            GridView1.DataSource = DT;
            GridView1.DataBind();
        }
    }

    protected void GridView1_Sorting(object sender, GridViewSortEventArgs e) {

        string query = "SELECT * FROM book";
        DataTable DT = new DataTable();
        SqlDataAdapter DA = new SqlDataAdapter(query, sqlCon);
        DA.Fill(DT);

        GridView1.DataSource = DT;
        GridView1.DataBind();

        if (DT != null) {
            DataView dataView = new DataView(DT);
            dataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection);

            GridView1.DataSource = dataView;
            GridView1.DataBind();
        }
    }

    private string GridViewSortDirection {
        get { return ViewState["SortDirection"] as string ?? "DESC"; }
        set { ViewState["SortDirection"] = value; }
    }

    private string ConvertSortDirectionToSql(SortDirection sortDirection) {
        switch (GridViewSortDirection) {
            case "ASC":
                GridViewSortDirection = "DESC";
                break;

            case "DESC":
                GridViewSortDirection = "ASC";
                break;
        }

        return GridViewSortDirection;
    }
}

Ответ Таркуса работает хорошо. Однако я бы предложил заменить VIEWSTATE на SESSION.

VIEWSTATE текущей страницы работает только тогда, когда текущая страница отправляется обратно на себя, и исчезает, как только пользователь перенаправляется на другую страницу. СЕССИЯ сохраняет порядок сортировки не только на постбэк текущей страницы. Это сохраняется в течение всей продолжительности сеанса. Это означает, что пользователь может перемещаться по другим страницам, и когда он возвращается на заданную страницу, порядок сортировки, который он использовал в последний раз, все еще остается. Это обычно более удобно.

Есть и другие методы, такие как сохранение пользовательских профилей.

Я рекомендую эту статью для очень хорошего объяснения ViewState и его работы с жизненным циклом веб-страницы: https://msdn.microsoft.com/en-us/library/ms972976.aspx

Чтобы понять разницу между VIEWSTATE, SESSION и другими способами сохранения переменных, я рекомендую эту статью: https://msdn.microsoft.com/en-us/library/75x4ha6s.aspx

Более простой способ...:

    Dim dt As DataTable = DirectCast(GridView1.DataSource, DataTable)
    Dim dv As New DataView(dt)

    If GridView1.Attributes("dir") = SortDirection.Ascending Then
        dv.Sort = e.SortExpression & " DESC" 
        GridView1.Attributes("dir") = SortDirection.Descending

    Else
        GridView1.Attributes("dir") = SortDirection.Ascending
        dv.Sort = e.SortExpression & " ASC"

    End If

    GridView1.DataSource = dv
    GridView1.DataBind()

Я нашел гораздо более простой способ, который позволяет вам по-прежнему использовать встроенную сортировку / разбиение по страницам стандартного gridview...

создать 2 ярлыка. установить их, чтобы быть видимым = ложь. Я назвал мои lblSort1 и lblSortDirection1

затем код 2 простых события... сортировка страницы, которая записывает в текст невидимые метки, и изменение индекса страницы, который использует их...

Private Sub gridview_Sorting(sender As Object, e As GridViewSortEventArgs) Handles gridview.Sorting
lblSort1.Text = e.SortExpression
lblSortDirection1.Text = e.SortDirection
End Sub

Private Sub gridview_PageIndexChanging(sender As Object, e As GridViewPageEventArgs) Handles gridview.PageIndexChanging
    gridview.Sort(lblSort1.Text, CInt(lblSortDirection1.Text))
End Sub

это немного медленнее, чем использование глобальных переменных, но с asp я обнаружил, что глобальные переменные ненадежны...

Другие вопросы по тегам