code

GridView 정렬 : SortDirection 항상 오름차순

codestyles 2020. 11. 13. 08:13
반응형

GridView 정렬 : SortDirection 항상 오름차순


Gridview가 있고 사용자가 헤더를 클릭 할 때 해당 요소를 정렬해야합니다.
데이터 소스는 List 객체입니다.

aspx는 다음과 같이 정의됩니다.

<asp:GridView ID="grdHeader" AllowSorting="true" AllowPaging="false" 
    AutoGenerateColumns="false" Width="780" runat="server"  OnSorting="grdHeader_OnSorting" EnableViewState="true">
    <Columns>
        <asp:BoundField DataField="Entitycode" HeaderText="Entity" SortExpression="Entitycode" />
        <asp:BoundField DataField="Statusname" HeaderText="Status" SortExpression="Statusname" />
        <asp:BoundField DataField="Username" HeaderText="User" SortExpression="Username" />
    </Columns>
</asp:GridView>

뒤에있는 코드는 다음과 같이 정의됩니다.
First load :

protected void btnSearch_Click(object sender, EventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();
    this.grdHeader.DataSource = items;
    this.grdHeader.DataBind();
}

사용자가 헤더를 클릭 할 때 :

protected void grdHeader_OnSorting(object sender, GridViewSortEventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();
    items.Sort(new Helpers.GenericComparer<V_ReportPeriodStatusEntity>(e.SortExpression, e.SortDirection));
    grdHeader.DataSource = items;
    grdHeader.DataBind();
}

내 문제는 e.SortDirection이 항상 오름차순으로 설정되어 있다는 것입니다.
비슷한 코드를 가진 웹 페이지가 있고 잘 작동합니다 .e.SortDirection은 오름차순과 내림차순을 번갈아 가며 나타납니다.

내가 뭘 잘못 했어?


세션 변수를 사용하여 최신 정렬 식을 저장하고 다음에 그리드를 정렬 할 때 그리드의 정렬 식을 마지막 정렬 식을 저장하는 세션 변수와 비교할 수 있습니다. 열이 같으면 이전 정렬의 방향을 확인하고 반대 방향으로 정렬합니다.

예:

DataTable sourceTable = GridAttendence.DataSource as DataTable;
DataView view = new DataView(sourceTable);
string[] sortData = ViewState["sortExpression"].ToString().Trim().Split(' ');
if (e.SortExpression == sortData[0])
{
    if (sortData[1] == "ASC")
    {
        view.Sort = e.SortExpression + " " + "DESC";
        this.ViewState["sortExpression"] = e.SortExpression + " " + "DESC";
    }
    else
    {
        view.Sort = e.SortExpression + " " + "ASC";
        this.ViewState["sortExpression"] = e.SortExpression + " " + "ASC";
    }
}
else
{
    view.Sort = e.SortExpression + " " + "ASC";
    this.ViewState["sortExpression"] = e.SortExpression + " " + "ASC";
}

Session 및 Viewstate의 문제는 페이지에 둘 이상의 gridview가있는 경우 SortColumn 및 Direction이 저장되는 gridview 컨트롤도 추적해야한다는 것입니다.

Session 및 Viewstate의 대안은 Gridview에 2 개의 속성을 추가하고 그런 방식으로 Column 및 Direction을 추적하는 것입니다.

다음은 그 예입니다.

private void GridViewSortDirection(GridView g, GridViewSortEventArgs e, out SortDirection d, out string f)
{
    f = e.SortExpression;
    d = e.SortDirection;

    //Check if GridView control has required Attributes
    if (g.Attributes["CurrentSortField"] != null && g.Attributes["CurrentSortDir"] != null)
    {
        if (f == g.Attributes["CurrentSortField"])
        {
            d = SortDirection.Descending;
            if (g.Attributes["CurrentSortDir"] == "ASC")
            {
                d = SortDirection.Ascending;
            }
        }

        g.Attributes["CurrentSortField"] = f;
        g.Attributes["CurrentSortDir"] = (d == SortDirection.Ascending ? "DESC" : "ASC");
    }

}

간단한 해결책 :

protected SortDirection GetSortDirection(string column)
{
    SortDirection nextDir = SortDirection.Ascending; // Default next sort expression behaviour.
    if (ViewState["sort"] != null && ViewState["sort"].ToString() == column)
    {   // Exists... DESC.
        nextDir = SortDirection.Descending;
        ViewState["sort"] = null;
    }
    else
    {   // Doesn't exists, set ViewState.
        ViewState["sort"] = column;
    }
    return nextDir;
}

ViewState의 기본 GridView 정렬 및 경량과 매우 유사합니다.

용법:

protected void grdHeader_OnSorting(object sender, GridViewSortEventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();

    items.Sort(new Helpers.GenericComparer<V_ReportPeriodStatusEntity>(e.SortExpression, GetSortDirection(e.SortExpression));
    grdHeader.DataSource = items;
    grdHeader.DataBind();
}

자동 양방향 정렬은 SQL 데이터 소스에서만 작동합니다. 불행히도 MSDN의 모든 문서는 당신이 그것을 사용하고 있다고 가정하므로 GridView는 약간 실망 스러울 수 있습니다.

내가하는 방법은 주문을 직접 추적하는 것입니다. 예를 들면 :

    protected void OnSortingResults(object sender, GridViewSortEventArgs e)
    {
        // If we're toggling sort on the same column, we simply toggle the direction. Otherwise, ASC it is.
        // e.SortDirection is useless and unreliable (only works with SQL data source).
        if (_sortBy == e.SortExpression)
            _sortDirection = _sortDirection == SortDirection.Descending ? SortDirection.Ascending : SortDirection.Descending;
        else
            _sortDirection = SortDirection.Ascending;

        _sortBy = e.SortExpression;

        BindResults();
    }

이 문제는 SQL 데이터 소스뿐만 아니라 개체 데이터 소스에서도 발생하지 않습니다. 그러나 코드에서 DataSource를 동적으로 설정할 때 이것이 잘못되었습니다. 불행히도 MSDN은 때때로 정보가 매우 부족합니다. 이 동작을 간단히 언급하면 ​​(버그가 아니라 디자인 문제) 많은 시간을 절약 할 수 있습니다. 어쨌든 나는 이것을 위해 세션 변수를 사용하는 경향이별로 없습니다. 나는 보통 ViewState에 정렬 방향을 저장합니다.


내가 한 방식은 수락 된 답변이 제공 한 코드와 비슷합니다. 비트가 약간 다르기 때문에 거기에 넣을 것이라고 생각했습니다. 이 정렬은 GridView .DataSource 에 바인딩되기 전에 DataTable에 대해 수행됩니다 .

옵션 1 : ViewState 사용

void DataGrid_Sorting(object sender, GridViewSortEventArgs e)
{
    if (e.SortExpression == (string)ViewState["SortColumn"])
    {
        // We are resorting the same column, so flip the sort direction
        e.SortDirection = 
            ((SortDirection)ViewState["SortColumnDirection"] == SortDirection.Ascending) ? 
            SortDirection.Descending : SortDirection.Ascending;
    }
    // Apply the sort
    this._data.DefaultView.Sort = e.SortExpression +
        (string)((e.SortDirection == SortDirection.Ascending) ? " ASC" : " DESC");
    ViewState["SortColumn"] = e.SortExpression;
    ViewState["SortColumnDirection"] = e.SortDirection;
}

옵션 2 : 세션 사용

다음은 현장에서 보거나 이전 브라우저를 대상으로하는 회사 시스템을 계속 지원하는 경우 레거시 목적으로 제공됩니다.

void DataGrid_Sorting(object sender, GridViewSortEventArgs e)
{
    if (e.SortExpression == (string)HttpContext.Current.Session["SortColumn"])
    {
        // We are resorting the same column, so flip the sort direction
        e.SortDirection = 
            ((SortDirection)HttpContext.Current.Session["SortColumnDirection"] == SortDirection.Ascending) ? 
            SortDirection.Descending : SortDirection.Ascending;
    }
    // Apply the sort
    this._data.DefaultView.Sort = e.SortExpression +
        (string)((e.SortDirection == SortDirection.Ascending) ? " ASC" : " DESC");
    HttpContext.Current.Session["SortColumn"] = e.SortExpression;
    HttpContext.Current.Session["SortColumnDirection"] = e.SortDirection;
}

왜 모두가 숨겨진 필드를 사용하는 것을 잊는 지 모르겠습니다! 그것들은 ViewState (2005 년 이후로 꺼 졌던)보다 훨씬 "저렴"합니다. Session 또는 ViewState를 사용하지 않으려면 다음은 내 솔루션입니다.

이 두 개의 숨겨진 필드를 aspx 페이지에 넣고 데이터에 대해 원하는 기본 정렬을 입력하십시오 (예를 들어 LastName을 사용하고 있습니다).

<asp:HiddenField ID="hfSortExpression" runat="server" Value="LastName" />
<asp:HiddenField ID="hfSortDirection" runat="server" Value="Ascending" />

그런 다음이 도우미 코드를 기본 페이지에 넣으십시오 (기본 페이지가 있습니까? 그렇지 않은 경우 .cs 코드를 뒤에 넣으십시오).

/// <summary>
/// Since native ASP.Net GridViews do not provide accurate SortDirections, 
/// we must save a hidden field with previous sort Direction and Expression.
/// Put these two hidden fields on page and call this method in grid sorting event
/// </summary>
/// <param name="hfSortExpression">The hidden field on page that has the PREVIOUS column that is sorted on</param>
/// <param name="hfSortDirection">The hidden field on page that has the PREVIOUS sort direction</param>
protected SortDirection GetSortDirection(GridViewSortEventArgs e, HiddenField hfSortExpression, HiddenField hfSortDirection)
{
    //assume Ascending always by default!!
    SortDirection sortDirection = SortDirection.Ascending;

    //see what previous column (if any) was sorted on
    string previousSortExpression = hfSortExpression.Value;
    //see what previous sort direction was used
    SortDirection previousSortDirection = !string.IsNullOrEmpty(hfSortDirection.Value) ? ((SortDirection)Enum.Parse(typeof(SortDirection), hfSortDirection.Value)) : SortDirection.Ascending;

    //check if we are now sorting on same column
    if (e.SortExpression == previousSortExpression)
    {
        //check if previous direction was ascending
        if (previousSortDirection == SortDirection.Ascending)
        {
            //since column name matches but direction doesn't, 
            sortDirection = SortDirection.Descending;
        }
    }

    // save them back so you know for next time
    hfSortExpression.Value = e.SortExpression;
    hfSortDirection.Value = sortDirection.ToString();

    return sortDirection;
}

다음으로 그리드 정렬 이벤트 핸들러에서 정렬을 처리해야합니다. 데이터를 가져 오는 기본 메서드를 호출하기 전에 정렬 이벤트 처리기에서 위의 메서드를 호출합니다.

protected void gridContacts_Sorting(object sender, GridViewSortEventArgs e)
{
    //get the sort direction (since GridView sortDirection is not implemented!)
    SortDirection sortDirection = GetSortDirection(e, hfSortExpression, hfSortDirection);

    //get data, sort and rebind (obviously, this is my own method... you must replace with your own)
    GetCases(_accountId, e.SortExpression, sortDirection);
}

많은 예제가 DataTables 또는 DataViews 또는 기타 LINQ 친화적이지 않은 컬렉션을 사용하기 때문에 일반 목록을 반환하는 중간 계층 메서드에 대한 호출을 포함하고 LINQ를 사용하여 반올림하기 위해 정렬을 수행 할 것이라고 생각했습니다. 예를 들어 더 "실제 세계"로 만듭니다.

private void GetCases(AccountID accountId, string sortExpression, SortDirection sortDirection)
{
    //get some data from a middle tier method (database etc._)(
    List<PendingCase> pendingCases = MyMiddleTier.GetCasesPending(accountId.Value);
    //show a count to the users on page (this is just nice to have)
    lblCountPendingCases.Text = pendingCases.Count.ToString();
    //do the actual sorting of your generic list of custom objects
    pendingCases = Sort(sortExpression, sortDirection, pendingCases);
    //bind your grid
    grid.DataSource = pendingCases;
    grid.DataBind();
}

마지막으로 사용자 지정 개체의 제네릭 목록에서 LINQ를 사용하는 다운 및 더티 정렬이 있습니다. 나는 트릭을 할 더 멋진 무언가가 있다고 확신하지만 이것은 개념을 보여줍니다.

private static List Sort (string sortExpression, SortDirection sortDirection, List pendingCases) {

    switch (sortExpression)
    {
        case "FirstName":
            pendingCases = sortDirection == SortDirection.Ascending ? pendingCases.OrderBy(c => c.FirstName).ToList() : pendingCases.OrderByDescending(c => c.FirstName).ToList();
            break;
        case "LastName":
            pendingCases = sortDirection == SortDirection.Ascending ? pendingCases.OrderBy(c => c.LastName).ToList() : pendingCases.OrderByDescending(c => c.LastName).ToList();
            break;
        case "Title":
            pendingCases = sortDirection == SortDirection.Ascending ? pendingCases.OrderBy(c => c.Title).ToList() : pendingCases.OrderByDescending(c => c.Title).ToList();
            break;
        case "AccountName":
            pendingCases = sortDirection == SortDirection.Ascending ? pendingCases.OrderBy(c => c.AccountName).ToList() : pendingCases.OrderByDescending(c => c.AccountName).ToList();
            break;
        case "CreatedByEmail":
            pendingCases = sortDirection == SortDirection.Ascending ? pendingCases.OrderBy(c => c.CreatedByEmail).ToList() : pendingCases.OrderByDescending(c => c.CreatedByEmail).ToList();
            break;
        default:
            break;
    }
    return pendingCases;
}

마지막으로 (이미 말했습니까?) Page_Load 핸들러에 이와 같은 것을 넣어 페이지로드시 그리드가 기본적으로 바인딩되도록 할 수 있습니다. _accountId는 사용자 지정으로 변환 된 쿼리 문자열 매개 변수입니다. 이 경우 내 자신의 AccountID 유형 ...

    if (!Page.IsPostBack)
    {
        //sort by LastName ascending by default
        GetCases(_accountId,hfSortExpression.Value,SortDirection.Ascending);
    }

그 모든 대답은 완전히 정확하지 않습니다. 나는 그것을 사용합니다 :

protected void SetPageSort(GridViewSortEventArgs e) 
        { 
            if (e.SortExpression == SortExpression) 
            { 
                if (SortDirection == "ASC") 
                { 
                    SortDirection = "DESC"; 
                } 
                else 
                { 
                    SortDirection = "ASC"; 
                } 
            } 
            else 
            {
                if (SortDirection == "ASC")
                {
                    SortDirection = "DESC";
                }
                else
                {
                    SortDirection = "ASC";
                } 
                SortExpression = e.SortExpression; 
            } 
        } 
  protected void gridView_Sorting(object sender, GridViewSortEventArgs e)
        {
            SetPageSort(e); 

gridView_Sorting에서 ...


다른 하나 :) 열 이름을 하드 코딩 할 필요가 없습니다.

DataTable dt = GetData();

    SortDirection sd;
    string f;
    GridViewSortDirection(gvProductBreakdown, e, out sd, out f);
    dt.DefaultView.Sort = sd == SortDirection.Ascending ? f + " asc" : f + " desc";
    gvProductBreakdown.DataSource = dt;
    gvProductBreakdown.DataBind();

Ant 다음 :

 private void GridViewSortDirection(GridView g, GridViewSortEventArgs e, out SortDirection d, out string f)
    {
        f = e.SortExpression;
        d = e.SortDirection;
 if (g.Attributes[f] != null)
        {
            d = g.Attributes[f] == "ASC" ? SortDirection.Descending : SortDirection.Ascending;

            g.Attributes[f] = d == SortDirection.Ascending ? "ASC" : "DESC";
        }
        else
        {
            g.Attributes[f] = "ASC";
            d = SortDirection.Ascending;
        }

View State 또는 Session을 사용하지 않고 수행 할 수 있습니다. 현재 순서는 정렬 기준이되는 열의 첫 번째 및 마지막 행의 값을 기준으로 결정할 수 있습니다.

        protected void gvItems_Sorting(object sender, GridViewSortEventArgs e)
    {
        GridView grid = sender as GridView; // get reference to grid
        SortDirection currentSortDirection = SortDirection.Ascending; // default order

        // get column index by SortExpression
        int columnIndex = grid.Columns.IndexOf(grid.Columns.OfType<DataControlField>()
                                      .First(x => x.SortExpression == e.SortExpression));

        // sort only if grid has more than 1 row
        if (grid.Rows.Count > 1)
        {
            // get cells
            TableCell firstCell = grid.Rows[0].Cells[columnIndex];
            TableCell lastCell = grid.Rows[grid.Rows.Count - 1].Cells[columnIndex];

            // if field type of the cell is 'TemplateField' Text property is always empty.
            // Below assumes that value is binded to Label control in 'TemplateField'.
            string firstCellValue = firstCell.Controls.Count == 0 ? firstCell.Text : ((Label)firstCell.Controls[1]).Text;
            string lastCellValue = lastCell.Controls.Count == 0 ? lastCell.Text : ((Label)lastCell.Controls[1]).Text;

            DateTime tmpDate;
            decimal tmpDecimal;

            // try to determinate cell type to ensure correct ordering
            // by date or number
            if (DateTime.TryParse(firstCellValue, out tmpDate)) // sort as DateTime
            {
                currentSortDirection = 
                    DateTime.Compare(Convert.ToDateTime(firstCellValue), 
                                     Convert.ToDateTime(lastCellValue)) < 0 ? 
                                            SortDirection.Ascending : SortDirection.Descending;
            }
            else if (Decimal.TryParse(firstCellValue, out tmpDecimal)) // sort as any numeric type
            {
                currentSortDirection = Decimal.Compare(Convert.ToDecimal(firstCellValue), 
                                                       Convert.ToDecimal(lastCellValue)) < 0 ? 
                                                       SortDirection.Ascending : SortDirection.Descending;
            }
            else // sort as string
            {
                currentSortDirection = string.CompareOrdinal(firstCellValue, lastCellValue) < 0 ? 
                                                             SortDirection.Ascending : SortDirection.Descending;
            }
        }

        // then bind GridView using correct sorting direction (in this example I use Linq)
        if (currentSortDirection == SortDirection.Descending)
        {
            grid.DataSource = myItems.OrderBy(x => x.GetType().GetProperty(e.SortExpression).GetValue(x, null));
        }
        else
        {
            grid.DataSource = myItems.OrderByDescending(x => x.GetType().GetProperty(e.SortExpression).GetValue(x, null));
        }

        grid.DataBind();
    }

        <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="TOTAL BOOK" SortExpression="totalbook"  />
                <asp:BoundField DataField="availablebook" HeaderText="AVAILABLE BOOK" />
//gridview code on page load under ispostback false//after that.



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;
    }
}

이것은 아마도 여기에 묻힐 것이지만 내 상황에 잘 맞는 해결책을 생각해 냈습니다.

양식로드 이벤트는 다음과 같습니다.

private DataTable DataTable1;
protected void Page_Load(object sender, EventArgs e)
{
  DataTable1 = GetDataFromDatabase();
  this.GridView1.DataSource = DataTable1.DefaultView;
  this.GridView1.DataBind();
}

페이지에 두 개의 숨겨진 필드를 추가하십시오.

<asp:HiddenField runat="server" ID="lastSortDirection" />
<asp:HiddenField runat="server" ID="lastSortExpression" />

asp : GridView 개체에 다음을 추가합니다.

AllowSorting="True" OnSorting="GridView1_Sorting"

다음 GridView 정렬 이벤트 사용

protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
    if (lastSortExpression.Value == e.SortExpression.ToString())
    {
        if (lastSortDirection.Value == SortDirection.Ascending.ToString())
        {
            e.SortDirection = SortDirection.Descending;
        }
        else
        {
            e.SortDirection = SortDirection.Ascending;
        }
        lastSortDirection.Value = e.SortDirection.ToString();
        lastSortExpression.Value = e.SortExpression;
    }
    else
    {
        lastSortExpression.Value = e.SortExpression;
        e.SortDirection = SortDirection.Ascending;
        lastSortDirection.Value = e.SortDirection.ToString();
    }

    DataView dv = DataTable1.DefaultView;
    if (e.SortDirection == SortDirection.Ascending)
    {
        dv.Sort = e.SortExpression;
    }
    else
    {
        dv.Sort = e.SortExpression + " DESC";
    }

    DataTable1 = dv.ToTable();
    GridView1.DataSource = DataTable1.DefaultView;
    GridView1.DataBind();
}

이제 내 gridview의 모든 열이 열이 변경 될 경우 추가 변경없이 정렬됩니다.


GridView를 사용한 지 오래되었지만 OnSorting 메서드를 떠나기 전에 그리드의 SortDirection 속성을 현재 상태로 설정해야한다고 생각합니다.

그래서....

List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();
items.Sort(new Helpers.GenericComparer<V_ReportPeriodStatusEntity>(e.SortExpression, e.SortDirection));
grdHeader.SortDirection = e.SortDirection.Equals(SortDirection.Ascending) ? SortDirection.Descending : SortDirection.Ascending;
grdHeader.DataSource = items;
grdHeader.DataBind();


이 문제를 다루는 데 지쳐서 정렬 방향과 정렬 열을 ViewState에 넣습니다 ....


오름차순과 내림차순을 전환하려면 앱의 BasePage에서 메서드를 사용하여 정렬 식과 정렬 방향을 캐시합니다.

protected void SetPageSort(GridViewSortEventArgs e)
{
    if (e.SortExpression == SortExpression)
    {
        if (SortDirection == "ASC")
        {
            SortDirection = "DESC";
        }
        else
        {
            SortDirection = "ASC";
        }
    }
    else
    {
        SortDirection = "ASC";
        SortExpression = e.SortExpression;
    }
}

SortExpression 및 SortDirection은 모두 ViewState에서 해당 값을 저장하고 검색하는 BasePage의 속성입니다.

따라서 내 모든 파생 페이지는 GridView의 Sorting 메서드에서 SetPageSort를 호출하고 GridView를 바인딩합니다.

protected void gv_Sorting(object sender, GridViewSortEventArgs e)
{
    SetPageSort(e);
    BindGrid();
}

BindGrid는 SortExpression을 확인하고 SortExpression과 SortDirection을 사용하여 그리드의 데이터 원본에서 ORDERY BY를 수행합니다.

if (SortExpression.Length > 0)
{
    qry.ORDER_BY(SortExpression + " " + SortDirection);
}

gv.DataSource = qry.ExecuteReader();
gv.DataBind();

따라서 기본 클래스의 SetPageSort는 GridView 정렬의 번거 로움을 상당 부분 제거합니다. 뭔가 잊은 것 같지만 그게 일반적인 생각입니다.


XML :

<asp:BoundField DataField="DealCRMID" HeaderText="Opportunity ID"
 SortExpression="DealCRMID"/>
<asp:BoundField DataField="DealCustomerName" HeaderText="Customer" 
 SortExpression="DealCustomerName"/>
<asp:BoundField DataField="SLCode" HeaderText="Practice" 
 SortExpression="SLCode"/>

암호:

private string ConvertSortDirectionToSql(String sortExpression,SortDirection sortDireciton)
{
    switch (sortExpression)
    {
        case "DealCRMID":
             ViewState["DealCRMID"]=ChangeSortDirection(ViewState["DealCRMID"].ToString());
             return ViewState["DealCRMID"].ToString();

        case "DealCustomerName":
             ViewState["DealCustomerName"] = ChangeSortDirection(ViewState["DealCustomerName"].ToString());
             return ViewState["DealCustomerName"].ToString();

        case "SLCode":
             ViewState["SLCode"] = ChangeSortDirection(ViewState["SLCode"].ToString());
             return ViewState["SLCode"].ToString();

        default:
            return "ASC";
    }       
}

private string ChangeSortDirection(string sortDireciton)
{
    switch (sortDireciton)
    {
        case "DESC":
            return "ASC";
        case "ASC":
            return "DESC";
        default:
            return "ASC";
    }
}

protected void gvPendingApprovals_Sorting(object sender, GridViewSortEventArgs e)
{
    DataSet ds = (System.Data.DataSet)(gvPendingApprovals.DataSource);

    if(ds.Tables.Count>0)
    {
        DataView m_DataView = new DataView(ds.Tables[0]);
        m_DataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql   (e.SortExpression.ToString(), e.SortDirection);

        gvPendingApprovals.DataSource = m_DataView;
        gvPendingApprovals.DataBind();
    }
}

이것은 문제를 해결하는 또 다른 방법입니다.

protected void grdHeader_OnSorting(object sender, GridViewSortEventArgs e)
{
    List<V_ReportPeriodStatusEntity> items = GetPeriodStatusesForScreenSelection();
    items.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e);
    grdHeader.DataSource = items;
    grdHeader.DataBind();
}

private string ConvertSortDirectionToSql(GridViewSortEventArgs e)
{
    ViewState[e.SortExpression] = ViewState[e.SortExpression] ?? "ASC";
    ViewState[e.SortExpression] = (ViewState[e.SortExpression].ToString() == "ASC") ? "DESC" : "ASC";
    return ViewState[e.SortExpression].ToString();
}

오래된 문자열이지만 아마도 내 대답이 누군가를 도울 것입니다.

먼저 SqlDataSource를 DataView로 가져옵니다.

Private Sub DataGrid1_SortCommand(ByVal source As Object, ByVal e As DataGridSortCommandEventArgs) Handles grid1.SortCommand
    Dim dataView As DataView = CType(SqlDataSource1.Select(DataSourceSelectArguments.Empty), DataView)
    dataView.Sort = e.SortExpression + dataView.FieldSortDirection(Session, e.SortExpression)

    grid1.DataSourceID = Nothing
    grid1.DataSource = dataView
    grid1.DataBind()

End Sub

그런 다음 확장 방법을 사용하여 정렬합니다 (일종의 치프 샷이지만 좋은 시작).

public static class DataViewExtensions
{
    public static string FieldSortDirection(this DataView dataView, HttpSessionState session, string sortExpression)
    {
        const string SORT_DIRECTION = "SortDirection";
        var identifier = SORT_DIRECTION + sortExpression;

        if (session[identifier] != null)
        {
            if ((string) session[identifier] == " ASC")
                session[identifier] = " DESC";
            else if ((string) session[identifier] == " DESC")
                session[identifier] = " ASC";
        }
        else
            session[identifier] = " ASC";

        return (string) session[identifier];
    }
}

의 SecretSquirrel 솔루션 사용

여기에 내 전체 작업, 프로덕션 코드가 있습니다. dgvCoaches를 그리드보기 이름으로 변경하기 만하면됩니다.

... 그리드 바인딩 중

        dgvCoaches.DataSource = dsCoaches.Tables[0];
        ViewState["AllCoaches"] = dsCoaches.Tables[0];
        dgvCoaches.DataBind();

그리고 이제 정렬

protected void gridView_Sorting(object sender, GridViewSortEventArgs e)
{
    DataTable dt = ViewState["AllCoaches"] as DataTable;

    if (dt != null)
    {
        if (e.SortExpression == (string)ViewState["SortColumn"])
        {
            // We are resorting the same column, so flip the sort direction
            e.SortDirection =
                ((SortDirection)ViewState["SortColumnDirection"] == SortDirection.Ascending) ?
                SortDirection.Descending : SortDirection.Ascending;
        }
        // Apply the sort
        dt.DefaultView.Sort = e.SortExpression +
            (string)((e.SortDirection == SortDirection.Ascending) ? " ASC" : " DESC");
        ViewState["SortColumn"] = e.SortExpression;
        ViewState["SortColumnDirection"] = e.SortDirection; 

        dgvCoaches.DataSource = dt;
        dgvCoaches.DataBind();
    }
}

다음은 aspx 코드입니다.

<asp:GridView ID="dgvCoaches" runat="server" 
    CssClass="table table-hover table-striped" GridLines="None"  DataKeyNames="HealthCoachID" OnRowCommand="dgvCoaches_RowCommand"
    AutoGenerateColumns="False" OnSorting="gridView_Sorting" AllowSorting="true">
    <Columns>
        <asp:BoundField DataField="HealthCoachID" Visible="false" />
        <asp:BoundField DataField="LastName" HeaderText="Last Name" SortExpression="LastName" />
        <asp:BoundField DataField="FirstName" HeaderText="First Name" SortExpression="FirstName" />
        <asp:BoundField DataField="LoginName" HeaderText="Login Name" SortExpression="LoginName" />
        <asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" HtmlEncode="false" DataFormatString="<a href=mailto:{0}>{0}</a>" />
        <asp:TemplateField>
            <ItemTemplate>
                    <asp:LinkButton runat="server" BorderStyle="None" CssClass="btn btn-default" Text="<i class='glyphicon glyphicon-edit'></i>" CommandName="Update" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:LinkButton runat="server" OnClientClick="return ConfirmOnDelete();" BorderStyle="None" CssClass="btn btn-default" Text="<i class='glyphicon glyphicon-remove'></i>" CommandName="Delete" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <RowStyle CssClass="cursor-pointer" />
</asp:GridView>

나는 이것에 끔찍한 문제가 있었기 때문에 마침내 LINQ를 사용하여 DataTable을 뷰에 할당하기 전에 주문했습니다.

Dim lquery = From s In listToMap
             Select s
             Order By s.ACCT_Active Descending, s.ACCT_Name

특히 부울 필드를 정렬 할 때 DataView.Sort 및 DataGrid.Sort 메서드가 신뢰할 수 없음을 발견했습니다.

나는 이것이 누군가를 돕기를 바랍니다.


void dg_SortCommand(object source, DataGridSortCommandEventArgs e)
{
    DataGrid dg = (DataGrid) source;
    string sortField = dg.Attributes["sortField"];
    List < SubreportSummary > data = (List < SubreportSummary > ) dg.DataSource;
    string field = e.SortExpression.Split(' ')[0];
    string sort = "ASC";
    if (sortField != null)
    {
        sort = sortField.Split(' ')[0] == field ? (sortField.Split(' ')[1] == "DESC" ? "ASC" : "DESC") : "ASC";
    }
    dg.Attributes["sortField"] = field + " " + sort;
    data.Sort(new GenericComparer < SubreportSummary > (field, sort, null));
    dg.DataSource = data;
    dg.DataBind();
}

아마도 이것은 누군가를 도울 것입니다. 그것이 2014이기 때문인지 또는이 게시물이 해결하려고하는 문제를 이해하지 못하지만 다음과 같이 slickgrid를 사용하면 매우 간단합니다.

문제는 현재 정렬 설정이 무엇인지 '기억'하는 방법이므로 Asp.Net에 대한 제안이 해당 값을 보유하고 있습니다. 그러나 slickGrid는 현재 정렬 순서가 무엇인지 알려줄 수 있습니다.

asc desc 정렬을 전환하려면 grid.getSortColumns ()를 사용하여 현재 열 정렬이 무엇인지 알아낼 수 있습니다. 이것은 내가 한 일이지만 한 번에 한 열만 정렬하므로 안전하게 할 수 있습니다 : 'if (grid.getSortColumns () [0] .sortAsc)'

... 작동하는 내 코드는 다음과 같습니다.

    // Make sure you have sortable: true on the relevant column names or 
    // nothing happens as I found!!
    var columns = [
    { name: "FileName", id: "FileName", field: "FileName", width: 95, selectable: true, sortable: true },
    { name: "Type", id: "DocumentType", field: "DocumentType", minWidth: 105, width: 120, maxWidth: 120, selectable: true, sortable: true },
    { name: "ScanDate", id: "ScanDate", field: "ScanDate", width: 90, selectable: true, sortable: true }, ];

.. 평소와 같이 데이터를로드 한 다음 정렬 부분 :

   // Clicking on a column header fires this event. Here we toggle the sort direction
    grid.onHeaderClick.subscribe(function(e, args) {
        var columnID = args.column.id;

        if (grid.getSortColumns()[0].sortAsc) {
            grid.setSortColumn(args.column.id, true);
        }
        else {
            grid.setSortColumn(args.column.id, false);
        }
    });

    // The actual sort function is like this 
        grid.onSort.subscribe(function (e, args) {
            sortdir = args.sortAsc ? 1 : -1;
            sortcol = args.sortCol.field;

            //alert('in sort');

            // using native sort with comparer
            // preferred method but can be very slow in IE with huge datasets
            dataView.sort(comparer, args.sortAsc);
            grid.invalidateAllRows();
            grid.render();
        });

// Default comparer is enough for what I'm doing here ..
function comparer(a, b) {
    var x = a[sortcol], y = b[sortcol];
    return (x == y ? 0 : (x > y ? 1 : -1));
}

마지막으로 사이트에 SlickGrid 이미지 폴더가 포함되어 있는지 확인하고 선택하면 열에 asc / desc 화살표가 나타납니다. 누락 된 경우 텍스트는 기울임 꼴로 표시되지만 화살표는 나타나지 않습니다.


이것을 썼다. 그것은 나를 위해 일한다.

 protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
    {
        if (ViewState["sortExpression"] == null || ViewState["sortExpression"].ToString() != e.SortExpression.ToString())
            MyDataTable.DefaultView.Sort = e.SortExpression + " ASC";
        else
        {
            if (ViewState["SortDirection"].ToString() == "Ascending")
                MyDataTable.DefaultView.Sort = e.SortExpression = e.SortExpression + " DESC";
            else
                MyDataTable.DefaultView.Sort = e.SortExpression + " ASC";
        }

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

        ViewState["sortExpression"] = e.SortExpression;
        ViewState["SortDirection"] = e.SortDirection;
    }

방법은 다음과 같습니다. 여기에 많은 답변보다 훨씬 쉽습니다.

이 SortDirection 클래스 만들기

    // ==================================================
    // SortByDirection
    // ==================================================
    public SortDirection SortByDirection
    {
        get
        {
            if (ViewState["SortByDirection"] == null)
            {
                ViewState["SortByDirection"] = SortDirection.Ascending;
            }

            return (SortDirection)Enum.Parse(typeof(SortDirection), ViewState["SortByDirection"].ToString());
        }
        set { ViewState["SortByDirection"] = value; }
    }

그런 다음 다음과 같이 정렬 기능에서 사용하십시오.

            // Created Date
            if (sortBy == "CreatedDate")
            {
                if (SortByDirection == SortDirection.Ascending)
                {
                    data = data.OrderBy(x => x.CreatedDate).ToList();
                    SortByDirection = SortDirection.Descending;
                }
                else {
                    data = data.OrderByDescending(x => x.CreatedDate).ToList();
                    SortByDirection = SortDirection.Ascending;
                } 
            }

protected void gv_Sorting(object sender, GridViewSortEventArgs e)
{
    DataTable dataTable = (DataTable)Cache["GridData"];

    if (dataTable != null)
    {
        DataView dataView = new DataView(dataTable);
        string Field1 = e.SortExpression;
        string whichWay = "ASC";
        if (HttpContext.Current.Session[Field1] != null)
        {
            whichWay = HttpContext.Current.Session[Field1].ToString();
            if (whichWay == "ASC")
                whichWay = "DESC";
            else
                whichWay = "ASC";               
        }

        HttpContext.Current.Session[Field1] = whichWay;
        dataView.Sort = Field1 + " " + whichWay;      
        gv.DataSource = dataView;
        gv.DataBind();
    }
}

이전에 검색된 정보를 저장합니다.

    string SqlConn = ConfigurationManager.ConnectionStrings["Sql28"].ConnectionString;
    SqlConnection sqlcon = new SqlConnection(SqlConn);
    sqlcon.Open();

    SqlCommand cmd = new SqlCommand();
    cmd.Connection = sqlcon;
    cmd.CommandType = System.Data.CommandType.Text;
    cmd.CommandText = HttpContext.Current.Session["sql"].ToString();

    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
    DataTable employees = new DataTable();
    adapter.Fill(employees);

    gv.DataSource = employees;
    gv.DataBind();

    Cache.Insert("GridData", employees, null, System.Web.Caching.Cache.NoAbsoluteExpiration,new TimeSpan(0, 360000, 0));

vb.net에서는 매우 간단합니다!

Protected Sub grTicketHistory_Sorting(sender As Object, e As GridViewSortEventArgs) Handles grTicketHistory.Sorting

    Dim dt As DataTable = Session("historytable")
    If Session("SortDirection" & e.SortExpression) = "ASC" Then
        Session("SortDirection" & e.SortExpression) = "DESC"
    Else
        Session("SortDirection" & e.SortExpression) = "ASC"
    End If
    dt.DefaultView.Sort = e.SortExpression & " " & Session("SortDirection" & e.SortExpression)
    grTicketHistory.DataSource = dt
    grTicketHistory.DataBind()

End Sub

참고URL : https://stackoverflow.com/questions/250037/gridview-sorting-sortdirection-always-ascending

반응형