なぜ誰もが非表示フィールドの使用を忘れているのかわかりません! それらは、ViewState (2005 年以降オフにしていた) よりもはるかに「安価」です。Session または ViewState を使用したくない場合、私の解決策は次のとおりです。
これらの 2 つの非表示フィールドを 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);
}