2013-08-13 4 views
0

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

public partial class DynamicGridView : System.Web.UI.UserControl 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     if (_selectCmd != string.Empty) 
      BindData(); 
    } 

    private void BindData() 
    { 
     DataTable dt; 
     if (ViewState[gridView.ClientID + "datatable"] == null || (string)ViewState[gridView.ClientID + "selectCommand"] != _selectCmd) 
     { 
      ViewState[gridView.ClientID + "selectCommand"] = _selectCmd; 
      dt = Classes.SQL.GetDataTable(_selectCmd); 

      if (dt != null) 
      { 
       ViewState[gridView.ClientID + "datatable"] = dt; 
       if (dt.Columns.Count != gridView.Columns.Count) 
       { 
        gridView.Columns.Clear(); 
        foreach (DataColumn column in dt.Columns) 
         AddBoundField(column); 
       } 
      } 
     } 
     else 
      dt = (DataTable)ViewState[gridView.ClientID + "datatable"]; 

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

    private void AddBoundField(DataColumn column) 
    { 
     BoundField field = new BoundField(); 
     HandleCustomDataFormatting(ref field, column); 
     field.DataField = column.ColumnName; 
     field.HeaderText = column.ColumnName; 
     field.ReadOnly = true; 
     field.SortExpression = column.ColumnName; 
     field.ControlStyle.ForeColor = System.Drawing.ColorTranslator.FromHtml("#333333"); 
     field.ItemStyle.Width = System.Web.UI.WebControls.Unit.Pixel(70); 

     gridView.Columns.Add(field); 
    } 

    private void HandleCustomDataFormatting(ref BoundField field, DataColumn column) 
    { 
     if (column.DataType == typeof(System.DateTime)) 
      switch (column.ColumnName) 
      { 
       case "InvalidDate": 
       case "NewCustomerValidated": 
       case "ValidatedDate": 
        field.DataFormatString = "{0:d}";//exclude time info 
        break; 
       default: 
        field.DataFormatString = "{0:g}"; 
        break; 
      } 
    } 

    private string GetSortDirection(string sortColumn) 
    { 
     string sortDirection = "ASC"; 
     string lastSortColumn = (string)ViewState[gridView.ClientID + "SortExpression"]; 

     if (lastSortColumn != null && lastSortColumn == sortColumn) 
     { 
      string lastDirection = (string)ViewState[gridView.ClientID + "SortDirection"]; 
      if (lastDirection != null && lastDirection == "ASC") 
       sortDirection = "DESC"; 
     } 
     ViewState[gridView.ClientID + "SortExpression"] = sortColumn; 
     ViewState[gridView.ClientID + "SortDirection"] = sortDirection; 

     return sortDirection; 
    } 

    private string _selectCmd = string.Empty; 

    public string SelectCommand 
    { 
     set { _selectCmd = value; } 
    } 

    protected void GridView_Sorting(object sender, GridViewSortEventArgs e) 
    { 
     DataTable dt = (DataTable)ViewState[gridView.ClientID + "datatable"]; 
     dt.DefaultView.Sort = e.SortExpression + " " + GetSortDirection(e.SortExpression); 
     BindData(); 
    } 

    protected void GridView_PageChange(object sender, GridViewPageEventArgs e) 
    { 
     gridView.PageIndex = e.NewPageIndex; 
     BindData(); 
    } 
} 
+1

Сохраняете ли вы 'DataTable' и sql-команду в' ViewState'? Не делай этого. Бывший взрывает ViewState, который замедляет ваше приложение, поскольку он отправляет это viewstate между вашим клиентом и вашим сервером. Последнее небезопасно, хотите ли вы, чтобы каждый пользователь мог видеть ваши sql-запросы, декодируя ViewState? Используйте 'Session', если вам нужно его сохранить или перезагрузить из базы данных. –

+0

Также обратите внимание, что для запросов, которые генерируют большие объемы данных, вам может понадобиться просто извлечь одну страницу данных из БД, а затем перейти и получить новую страницу при каждом изменении страницы, если нецелесообразно хранить весь набор результатов в 'сессии'. – Servy

+0

Tim, это приложение предназначено для «внутреннего использования» только в локальной интрасети. Кроме того, он будет использоваться несколькими людьми, поэтому я не слишком беспокоюсь о том, что они видят SQL-запросы. Однако я согласен с вами по всем пунктам, которые вы сделали. Спасибо. – Chris

ответ

0

Вам не нужно связываться при загрузке каждой страницы.

if (_selectCmd != string.Empty) 
    if(!IsPostBack) 
      BindData(); 

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

0

Этот подход сработал для меня.

Вы можете настроить пару переменных быть что-то вроде этого:

protected string SortColummn 
{ 
    get { return ViewState["SortColumn"].ToString(); } 
    set { ViewState["SortColumn"] = value; } 
} 
protected string SortDirection 
{ 
    get { return ViewState["SortDirection"].ToString(); } 
    set { ViewState["SortDirection"] = value; } 
} 

Настройка значений по умолчанию для этих файлов в Page_Load в «если (Page.IsPostBack!)» Блок. Затем, в GridView_Sorting, установите эти две переменные на основе e.SortExpression. Наконец, в BindData() установите dt.DefaultView.Sort на основе этих двух переменных.

+0

Следует отметить, что приведенные выше комментарии об использовании Session vs. ViewState точны, но поскольку Крис сказал, что он не беспокоится об этих проблемах, я написал свое решение, используя viewstate. – BryPie

Смежные вопросы