C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

DataGridViewでソート時のレコード選択状態を保持

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■85296 / inTopicNo.1)  DataGridViewでソート時のレコード選択状態を保持
  
□投稿者/ うみ (9回)-(2017/10/05(Thu) 09:58:41)

分類:[C#] 

2017/10/05(Thu) 09:59:50 編集(投稿者)

VS2015/C#/Windowsフォームアプリケーション

いつもお世話になっております。

DataGridViewでタイトル行をクリックすると、クリックした列で
ソートが行われますが、このソート時に、選択した行が解除されてしまい
困っています。複数行選択することも可能としています。
ソート時に、選択が解除されない方法はありますでしょうか?

なお、DataGridViewのプロパティは、以下設定を行っています。
・AllowUserToAddRows = false; // 行追加を表示しない
・AllowUserToDeleteRows = false; // 行削除を行えない
・MultiSelect = True; // 複数行選択可
・ReadOnly = true; // 読み取り専用
・RowHeadersVisible = false; // 列ヘッダーを表示しない

よろしくお願いします。
引用返信 編集キー/
■85299 / inTopicNo.2)  Re[1]: DataGridViewでソート時のレコード選択状態を保持
□投稿者/ Hongliang (569回)-(2017/10/05(Thu) 13:24:36)
ちょっと検索した感じでは、あんまり決定版的なのは見当たりませんね。
CellClickイベントで選択中のを確保して、みたいなのが多い。
// これだとカーソルキーで選択した時に対応できない。

各列のSortModeをProgrammaticにしておいたうえで、
ColumnHeaderMouseClickイベントにて、
1. DataGridView::SelectedRowsから、選択しているデータを確保しておく。
2. DataGridView::Sort(DataGridViewColumn, ListSortDirection)メソッドでソートさせる。
3. 各行を見て回って、その行が1で確保したデータかどうかでSelectedを設定する。
という手順をとればいいですかね。件数が多いとパフォーマンスが心配になりますが。
DataSourceを使っているのであれば、「選択しているデータ」はDataRow::DataBoundItemを使用できます。
引用返信 編集キー/
■85301 / inTopicNo.3)  Re[1]: DataGridViewでソート時のレコード選択状態を保持
□投稿者/ kiku (15回)-(2017/10/05(Thu) 13:38:34)
検証していないので間違っているかもしれませんが
OnColumnHeaderMouseClickをoverrideすることで実現できないでしょうか?
ソートが実行される前に、選択行を保存しておき、
ソートが実行された後に、復元するような方向で。

    class MyDataGridView : DataGridView
    {
        protected override void OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)
        {
            //ソートが実行される前
            base.OnColumnHeaderMouseClick(e);
            //ソートが実行された後
        }
    }

引用返信 編集キー/
■85337 / inTopicNo.4)  Re[2]: DataGridViewでソート時のレコード選択状態を保持
□投稿者/ うみ (10回)-(2017/10/11(Wed) 09:36:41)
2017/10/11(Wed) 14:01:48 編集(投稿者)
ソースコードにバグがあったため、修正しました。



返信が遅くなってしまい、申し訳ありません。

Hongliang様、kiku様 ご教示いただきありがとうございます。

今回は、kiku様の方法で実現しました。
以下にソースコードを貼り付けます。
当方、初心者なため、きれいなソースコードではないのは、
ご了承ください。

以上

------------------------------
class MyDataGridView : DataGridView

// プロパティ追加
private bool m_SortSelectHold = false;     // ソート時に選択状態を保持
/// <summary>
/// ソート時に選択状態を保持
/// </summary>
[Category("追加")]
[Description("ソート時に選択状態を保持するか設定。")]
public bool SortSelectHold
{
    get
    {
        return m_SortSelectHold;
    }
    set
    {
        m_SortSelectHold = value;
    }
}

protected override void OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)
{
    List<string> listKey = new List<string>();

    // ソートが実行される前にソートキーを退避
    if (m_SortSelectHold)
    {
        foreach (DataGridViewRow row in SelectedRows)
        {
            listKey.Add(row.Cells[m_SortSelectHoldKeyCol].Value.ToString());
        }
    }

    // ベースのイベント
    base.OnColumnHeaderMouseClick(e);

    //ソートが実行された後、退避したキーのレコードを選択
    if (m_SortSelectHold)
    {
        bool bFirstFlg = true;

        foreach (var sKey in listKey)
        {
            DataGridViewRow[] rows = (from DataGridViewRow x in Rows
                                      where (string)x.Cells[列名].Value == sKey
                                      select x).ToArray();

            foreach (DataGridViewRow row in rows)
            {
                row.Selected = true;
                if (bFirstFlg)
                {
                    CurrentCell = this[0, row.Index];
                    bFirstFlg = false;
                }
            }
        }
    }
}

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ