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

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

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

visualStudio datagridview 昇順降順

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

■95127 / inTopicNo.1)  visualStudio datagridview 昇順降順
  
□投稿者/ ポテトサラダ爆発 (1回)-(2020/06/24(Wed) 21:03:33)

分類:[C#] 

開発環境:visualStudio2019
使用言語:C#

datagridviewコントロールでセル選択を行単位のみで行うよう設定してるのですが、
その際にdatagridviewの機能で昇順降順があるのですが、選択している行が
昇順降順されているのにフォーカス?が移動されません。
どのような処理またはプロパティ等の設定で、選択されているセルの行が、
昇順降順によって動くのでしょうか。

ご回答宜しくお願い致します。
引用返信 編集キー/
■95128 / inTopicNo.2)  Re[1]: visualStudio datagridview 昇順降順
□投稿者/ ポテトサラダ爆発 (3回)-(2020/06/24(Wed) 21:08:24)
No95127 (ポテトサラダ爆発 さん) に返信
> 開発環境:visualStudio2019
> 使用言語:C#
> 
> datagridviewコントロールでセル選択を行単位のみで行うよう設定してるのですが、
> その際にdatagridviewの機能で昇順降順があるのですが、選択している行が
> 昇順降順されているのにフォーカス?が移動されません。
> どのような処理またはプロパティ等の設定で、選択されているセルの行が、
> 昇順降順によって動くのでしょうか。
> 
> ご回答宜しくお願い致します。

引用返信 編集キー/
■95129 / inTopicNo.3)  Re[1]: visualStudio datagridview 昇順降順
□投稿者/ ポテトサラダ爆発 (4回)-(2020/06/24(Wed) 21:11:51)
datagridviewに関するソースコードは以下のようになっています。


        private void select_dataGridView()
        {
            string ConnectionString = @"Data Source=XXX;Persist Security Info=True;Initial Catalog=XXX;User ID=XXX;Password=XXX;";

            var cnn = new SqlConnection(ConnectionString);
            cnn.Open();

            var adapter = new SqlDataAdapter("SELECT [XXX_ID], [XXX], [XXX], [XXX] FROM [XXX]", cnn);

            var ds = new DataSet();

            adapter.Fill(ds);

            this.dataGridView1.DataSource = ds.Tables[0];

            dataGridView1.ReadOnly = true;                                               
            dataGridView1.AllowUserToDeleteRows = false;                                  
            dataGridView1.AllowUserToAddRows = false;                                     
            dataGridView1.AllowUserToResizeRows = false;                                              
            dataGridView1.RowHeadersVisible = false;                                      
            dataGridView1.MultiSelect = false;                                           
            dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;        

            dataGridView1.Columns[0].HeaderText = "XXX";
            dataGridView1.Columns[1].HeaderText = "XXX";
            dataGridView1.Columns[2].HeaderText = "XXX";
            dataGridView1.Columns[3].HeaderText = "XXX";



引用返信 編集キー/
■95131 / inTopicNo.4)  Re[1]: visualStudio datagridview 昇順降順
□投稿者/ 魔界の仮面弁士 (2760回)-(2020/06/24(Wed) 21:49:12)
No95127 (ポテトサラダ爆発 さん) に返信
> どのような処理またはプロパティ等の設定で、選択されているセルの行が、
> 昇順降順によって動くのでしょうか。

ごめんなさい。質問の意味が読み取れなかったです。

とりあえず下記を実行すると、
 ・ランダムな値がセットされた DataGridView が表示される。
 ・フォームを起動した時点で、[元の3行目]〜[元の5行目]および[元の11行目]が、行全体が選択された状態になっている。
 ・また、[元の8行目] とある行は選択されていないが、その左に、現在行を表す三角マークが出ている。
という状態になります。

この状態で後続の列ヘッダーをクリックすると、並び替えが行われますが、
並び替え後も、現在行は[元の8行目]と表示されている行のままですし、
選択されている行も[元の3行目]〜[元の5行目]および[元の11行目]のままでした。

この状態が都合が悪い…ということなのでしょうか?



// 空のフォームで実験
private void Form1_Load(object sender, EventArgs e)
{
  DataGridView dgv = new DataGridView();
  dgv.Dock = DockStyle.Fill;
  dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
  dgv.MultiSelect = true;
  Controls.Add(dgv);

  // 実験用のダミーデータ
  dgv.AllowUserToAddRows = false;
  dgv.RowCount = 30;
  dgv.ColumnCount = 10;
  Random rnd = new Random();
  for (int r = 0; r < 30; r++)
  {
    dgv[0,r].Value = "元の" + r + "行目";
    for (int c = 1; c < 10; c++)
    {
      dgv[c, r].Value = rnd.Next(1000, 9999);
    }
  }

  // 8行目の先頭列をカレントセルにするが、選択状態にはしない
  (dgv.CurrentCell = dgv[0, 8]).Selected = false;

  // 代わりに、3, 4, 5, 11 行目を選択しておく
  dgv.Rows[3].Selected = true;
  dgv.Rows[4].Selected = true;
  dgv.Rows[5].Selected = true;
  dgv.Rows[11].Selected = true;


  // この状態で列ヘッダーをクリックしてみよう
}



> datagridviewコントロールでセル選択を行単位のみで行うよう設定してるのですが、
SelectionMode = FullRowSelect のことですね。

その DataGridView では、データバインドを用いていますか?

もし DataGridView の DataSource にバインドしているとして、かつ、そのデータが
ソート非対応なデータをバインドしている場合は、並び替えのために追加の手間がかかりますが、
そういう状況ではないのですよね。



> その際にdatagridviewの機能で昇順降順があるのですが、
「昇順降順がある」というのは
ユーザーが列ヘッダーをクリックしてソートする機能のことで良いですか?
(その列の SortMode が Automatic に設定されている必要があります)

それとも、DataGridView の Sort メソッドの事でしょうか?
あるいは、バインドしている DataSource を、自身で昇順降順に並び替えてセットしている、という話でしょうか?



> 選択している行が昇順降順されているのにフォーカス?が移動されません。

ひとまず、フォーカスの後ろの「?」が気にかかりますが…。

質問頂いた説明を呼んでも、どういう状況なのか分かりませんでした。
もう少し具体的に説明して頂けると有難いです。


とりあえず、非編集状態のセルで Tab キーを押すと、そのセルが破線で囲まれた状態で
表示されると思いますが、これが DataGridView における「フォーカス」となります。

もしもフォーカスの破線を表示したくない場合には、下記のようにします。
https://dobon.net/vb/dotnet/datagridview/noforusframe.html


DataGridView において、フォーカスは一つのセルだけに割り当たる物であり、
行全体に対するフォーカスにはなりません。(独自描画をしてそれっぽく見せることはできますが)

ひとまず、行単位の「フォーカス」の代わりに、
 (1) 現在カーソルがある行(行ヘッダに右向き三角が付いている行)
 (2) 現在選択されている行(通常、青色などの選択色にて描画される)
にて代用できるかも知れません。やりたい内容にもよりますが。
引用返信 編集キー/
■95132 / inTopicNo.5)  Re[2]: visualStudio datagridview 昇順降順
□投稿者/ ポテトサラダ爆発 (5回)-(2020/06/24(Wed) 22:33:02)
No95131 (魔界の仮面弁士 さん) に返信
> この状態で後続の列ヘッダーをクリックすると、並び替えが行われますが、
> 並び替え後も、現在行は[元の8行目]と表示されている行のままですし、
> 選択されている行も[元の3行目]〜[元の5行目]および[元の11行目]のままでした。
>
> この状態が都合が悪い…ということなのでしょうか?

 返信が遅くなり、申し訳ございません。
 色々と説明不足でした。
 ↓の方に意図(魔界さんの質問の返答)を記述していきます。


>>datagridviewコントロールでセル選択を行単位のみで行うよう設定してるのですが、
> SelectionMode = FullRowSelect のことですね。

 その通りです。



> その DataGridView では、データバインドを用いていますか?
>
> もし DataGridView の DataSource にバインドしているとして、かつ、そのデータが
> ソート非対応なデータをバインドしている場合は、並び替えのために追加の手間がかかりますが、
> そういう状況ではないのですよね。

 データバインドは用いていません。
 SQLserverManagementStudio(SSMS)にSQL認証で接続しており、
 そこからSELECT文でデータを持ってきています。


>>その際にdatagridviewの機能で昇順降順があるのですが、
> 「昇順降順がある」というのは
> ユーザーが列ヘッダーをクリックしてソートする機能のことで良いですか?
> (その列の SortMode が Automatic に設定されている必要があります)
>
> それとも、DataGridView の Sort メソッドの事でしょうか?
> あるいは、バインドしている DataSource を、自身で昇順降順に並び替えてセットしている、という話でしょうか?

 前者の列ヘッダーをクリックしてのソート機能です。



>>選択している行が昇順降順されているのにフォーカス?が移動されません。
>
> ひとまず、フォーカスの後ろの「?」が気にかかりますが…。
>
> 質問頂いた説明を呼んでも、どういう状況なのか分かりませんでした。
> もう少し具体的に説明して頂けると有難いです。
>
>
> とりあえず、非編集状態のセルで Tab キーを押すと、そのセルが破線で囲まれた状態で
> 表示されると思いますが、これが DataGridView における「フォーカス」となります。
>
> もしもフォーカスの破線を表示したくない場合には、下記のようにします。
> https://dobon.net/vb/dotnet/datagridview/noforusframe.html
>
>
> DataGridView において、フォーカスは一つのセルだけに割り当たる物であり、
> 行全体に対するフォーカスにはなりません。(独自描画をしてそれっぽく見せることはできますが)
>
> ひとまず、行単位の「フォーカス」の代わりに、
>  (1) 現在カーソルがある行(行ヘッダに右向き三角が付いている行)
>  (2) 現在選択されている行(通常、青色などの選択色にて描画される)
> にて代用できるかも知れません。やりたい内容にもよりますが。

 Windowsフォームを作成し、テキストボックスやコンボボックスに入力(選択)した値を、
 作成した新規登録ボタン(INSERTの処理)や更新ボタン(UPDATEの処理)で
 SSMSの中にあるテーブルに書き込むことを目的とした業務システムのようなものを作成中です。

 データグリッドビューの用途しましては、
 SELECT文で取得したデータを反映させたグリッドビューから行を選択し、レコードの内容取得ボタンを押下した後、
 Windowsフォームのテキストボックスやコンボボックスに値を反映させ、データを編集し、更新をすることに使われます。

 実現したいこととして、データグリッドビューの1行目を選択し、青く囲まれている状態して
 列ヘッダーのソート機能を押下した際に、●←選択されている状態

【現状】
 |XXX_ID |名前 |所属 |  |XXX_ID |名前 |所属 |
●|001   |ああ |ああ | ●|003   |ああ |ああ |
 |002   |ああ |ああ |→ |002   |ああ |ああ |
 |003   |ああ |ああ |  |001   |ああ |ああ |

 から

【理想】
 |XXX_ID |名前 |所属 |  |XXX_ID |名前 |所属 |
●|001   |ああ |ああ |  |003   |ああ |ああ |
 |002   |ああ |ああ |→ |002   |ああ |ああ |
 |003   |ああ |ああ | ●|001   |ああ |ああ |

にしたいといった感じです。
 
引用返信 編集キー/
■95133 / inTopicNo.6)  Re[2]: visualStudio datagridview 昇順降順
□投稿者/ 魔界の仮面弁士 (2761回)-(2020/06/24(Wed) 23:22:02)
掲示板をリロードしなかったので、すれ違いになった…。orz

No95129 (ポテトサラダ爆発 さん) に返信
> this.dataGridView1.DataSource = ds.Tables[0];

データバインドしているのですね。

データバインド時の各行は、DataGridViewRow クラスのインスタンスを共有しているため、
ソート時の選択動作が、非バインド時とバインド時とで、異なる動作となります。


今回の場合、列ヘッダークリックによるソートは、
バインド元の ds.Tables[0].DefaultView.Sort を通じて行われます。

そのため、DefaultView を変更されたくない場合は、
 dataGridView1.DataSource = bindingSource1;
 bindingSource1.DataSource = ds.Tables[0];
あるいは、
 dataGridView1.DataSource = new DataView(ds.Tables[0]);
などとする必要があったりするわけですが、それはさておき。


上記の通り、データバインド時におけるソートは、DataGridView の機能としてではなく、
データソース側のソート機能に基づいて行われるようになっています。

そのため、ソート後の選択状態を維持したい場合は、

(1) DataGridView の選択状態が、バインド元データのどのレコードを指しているのかを保持しておく
(2) ソートが行われた後、保持しておいたデータが、DataGridView のどの行に該当するのかを逆引きし、選択状態を差し戻す

という作業が必要になります。


下記にサンプルを載せておきます。


private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
  var dgv = (DataGridView)sender;
  if (e.RowIndex >= 0 || dgv.SelectedRows.Count == 0) { return; }

  // 今回は MultiSelect = false なので SelectedRows[0] が指す元レコードのみを保持していますが、
  // 複数選択とする場合は、他の選択行も保持しておく必要があります。
  var gridRow = dgv.SelectedRows[0];
  selectedRow = ((DataRowView)gridRow.DataBoundItem).Row;
}
private DataRow selectedRow = null;
private void dataGridView1_Sorted(object sender, EventArgs e)
{
  if (selectedRow == null) { return; }
  var dgv = (DataGridView)sender;
  dgv.ClearSelection();
  foreach (DataGridViewRow gridRow in dgv.Rows)
  {
    if (((DataRowView)gridRow.DataBoundItem).Row == selectedRow)
    {
      // 下記の 2 行のうち、一方だけで良いのか、両方指定すべきかはケースバイケース
      dgv.CurrentCell = gridRow.Cells[0];
      gridRow.Selected = true;

      // 今回は単一行選択のため、「選択行」≒「現在行」といえますが、
      // MultiSelect = true モードでは「選択行」≠「現在行」になりえることに注意。

      break;
    }
  }
  selectedRow = null;
}
引用返信 編集キー/
■95134 / inTopicNo.7)  Re[2]: visualStudio datagridview 昇順降順
□投稿者/ ポテトサラダ爆発 (6回)-(2020/06/24(Wed) 23:43:37)
魔界さん、夜分遅くまで申し訳ございません。
自身の勉強不足でした。データバインドというのは
デザイン画面でデータグリッドビューの詳細からデータソースを
選択するという解釈をしていました。

個人ブログ等のサンプルソースの記述をちゃんと把握したうえで
掲示板等に質問ができる状態になるべく努力を致します。
解決済み
引用返信 編集キー/

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


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

このトピックに書きこむ