21

自然な並べ替え (エクスプローラーのように) を使用して DataGridView を並べ替える必要があるため、数字とテキスト (同じ列内) はアルファベット順ではなく自然に並べ替えられます (「場所 3」が「場所 20」などの前になるように)。DataGridView があり、DataView を DataSource として設定しました。DataView には、データベースからのいくつかの値で作成された DataTable が含まれています。列の型は文字列です。私は IComparer を持っています。これは本来あるべきことを行いますが、並べ替えの方法がわからないため、使用方法がわかりません。完璧なDataGridView.SortCompareイベントは、データバインドされているため機能しません。DataView.Sort は、列名と並べ替え順序を含む文字列のみを受け入れます。

とてもうるさい。ここで関連する問題を StackOverflow で読み込もうとし、グーグルでたくさん検索しましたが、これについてはあまり見つけられません。私が実際に見つけたのは、データビューの Sort(string) メソッドを使用していることだけです。これは、アルファベット順にソートされるため、機能しません。

あまり問題なくこれを行う方法を知っている人はいますか? これに苦労しているのは私以外の誰かにならなければなりませんか?カスタムソートを取得するためだけに、datagridviewまたはdataviewクラス全体を再実装したくありません...

更新:誰かが疑問に思っている場合に備えて、私はまだこの問題に対する良い答えを探しています. その間、私は自分の単純なテーブルクラスを作成し、それを手動でデータグリッドビューにフィードしました。SortCompare メソッドをオーバーライドします。少し面倒ですが、それほど難しくはありませんでした。値を表示するだけで (編集などは必要ありません)、すべてを文字列に変換できたからです。

4

5 に答える 5

5

この MSDN ページこのブログ投稿をご覧ください。原則として、GridView ではなく、データ ソース (ObjectDataSource または SqlDataSource) で並べ替えを構成する必要があります。

私が知る限り、DataView クラスは単純な昇順/降順の並べ替え以外はサポートしていません。データをロードしてバインドするコードを見ないと、特定の推奨事項を作成するのは困難ですが、次のいずれかを行うことができます。

  1. DataTable ではなく List にデータをロードし、Sort メソッドを呼び出して比較メソッドを渡してから、そのリストにバインドします。
  2. クラスから直接データを取得する aspx コードで ObjectDataSource を作成し、IComparer を使用するようにその ObjectDataSource を構成します。
于 2009-01-12T14:29:26.960 に答える
3

このコードは機能するはずです。ListView の ListViewItemSorter に似ています。IComparer を使用します。

使用するには:

private void dgv_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    MyDataGridHelper.DataGridSort(dgv, e.ColumnIndex);
}

MyDataGridHelper.cs:

public class MyDataGridHelper
{
    public static void DataGridSort(DataGridView dgv, int column)
    {
        DataGridViewCustomSorter dgvSorter = null;
        if (dgv.Tag == null || !(dgv.Tag is IComparer))
        {
            dgvSorter = new DataGridViewCustomSorter(dgv);
            dgv.Tag = dgvSorter;
        }
        else
        {
            dgvSorter = (DataGridViewCustomSorter)dgv.Tag;
        }
        dgvSorter.SortColumn = column;
        dgv.Sort(dgvSorter);
    }

    private class DataGridViewCustomSorter : IComparer
    {
        private int ColumnIndex;
        private SortOrder OrderOfSort;
        private DataGridView myDataGridView;
        private TypeCode mySortTypeCode;

        public DataGridViewCustomSorter(DataGridView dgv)
        {
            myDataGridView = dgv;
            mySortTypeCode = Type.GetTypeCode(Type.GetType("System.String"));
            ColumnIndex = 0;
            OrderOfSort = SortOrder.None;
        }

        public int Compare(object x, object y)
        {
            int result;
            DataGridViewRow dgvX, dgvY;

            dgvX = (DataGridViewRow)x;
            dgvY = (DataGridViewRow)y;
            string sx = dgvX.Cells[ColumnIndex].Value.ToString();
            string sy = dgvY.Cells[ColumnIndex].Value.ToString();

            //null handling
            if (sx == String.Empty && sy == String.Empty)
                result = 0;
            else if (sx == String.Empty && sy != String.Empty)
                result = -1;
            else if (sx != String.Empty && sy == String.Empty)
                result = 1;
            else
            {
                switch (mySortTypeCode)
                {
                    case TypeCode.Decimal:
                        Decimal nx = Convert.ToDecimal(sx);
                        Decimal ny = Convert.ToDecimal(sy);
                        result = nx.CompareTo(ny);
                        break;
                    case TypeCode.DateTime:
                        DateTime dx = Convert.ToDateTime(sx);
                        DateTime dy = Convert.ToDateTime(sy);
                        result = dx.CompareTo(dy);
                        break;
                    case TypeCode.String:
                        result = (new CaseInsensitiveComparer()).Compare(sx, sy);
                        break;
                    default:
                        result = (new CaseInsensitiveComparer()).Compare(sx, sy);
                        break;
                }
            }
            if (OrderOfSort == SortOrder.Descending)
                result = (-result);

            return result;
        }

        public int SortColumn
        {
            set
            {
                if (ColumnIndex == value)
                {
                    OrderOfSort = (OrderOfSort == SortOrder.Descending ? SortOrder.Ascending : SortOrder.Descending);
                }
                ColumnIndex = value;
                try
                {
                    mySortTypeCode = Type.GetTypeCode(Type.GetType((myDataGridView.Columns[ColumnIndex]).Tag.ToString()));
                }
                catch
                {
                    mySortTypeCode = TypeCode.String;
                }
            }
            get { return ColumnIndex; }
        }

        public SortOrder Order
        {
            set { OrderOfSort = value; }
            get { return OrderOfSort; }
        }
    } //end class DataGridViewCustomSorter
} //end class MyDataGridHelper
于 2012-01-03T23:10:02.223 に答える
1

「 SortCompare イベントを使用したカスタム並べ替え 」と「IComparer インターフェイスを使用したカスタム並べ替え」という解決策があります。

http://msdn.microsoft.com/en-us/library/ms171608.aspx

于 2010-11-17T10:18:36.797 に答える
0

並べ替えロジックをデータベース クエリに移動して、正しい並べ替え順序を持つ追加の列を返すようにすることができます。

次に(@True C Sharpの回答の行に沿って)この値を含む非表示の列を作成し、表示列ではなくこれで並べ替えることができます。

これは、ソート順を決定するためのロジックが SQL で実行できることを前提としています。並べ替え順序を決定するアルゴリズムが複雑な場合、これは機能しない可能性があります。

于 2012-03-16T12:45:31.510 に答える
0

非表示の列を 2 つ作成できます。テキスト部分を 1 番目の非表示列に、数字部分を 2 番目の非表示列に割り当てます。次に、これらの非表示の列で並べ替えます (1 番目の列のアルファ ソートと 2 番目の列の数値ソート)。

このようにして、表示目的で元の列を保持し、並べ替えのために 2 つの非表示の列を持つことができます。

于 2009-01-12T16:28:26.097 に答える