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

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

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

Re[4]: datagridviewの選択行について


(過去ログ 47 を表示中)

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

■25660 / inTopicNo.1)  datagridviewの選択行について
  
□投稿者/ ありあり (4回)-(2008/09/24(Wed) 13:51:31)

分類:[C#] 

開発環境:VisualStudio2005(C#) OS:windowsXP
で開発しております。

datagridviewでフォーカスを受け取った際に選択されている行の値を取得したいのですが、
1行目を最初にクリックした場合のみ、SelectedRowsに行が格納されていない現象が発生しています。

2行目以降を最初にクリックした場合や、他の行をクリックした後1行目をクリックするときちんと
SelectedRowに行が格納されています。

1行目をdatagridview.Rows[0].Cells[0].Selected=trueにすると、RowEnterイベント内で無限ループ
に陥るため、行を強制的に選択状態にすることはできません。

どなたか回避方法をご存知の方、ご教授よろしくお願いします。


///行が入力フォーカスを受け取り、現在の行になったとき発生するイベント(RowEnter)
///
private void datagridview_RowEnter_test(object sender, DataGridViewCellEventArgs e) {
    if (e.ColumnIndex < 0 || e.RowIndex < 0) {
        return;
    }
    Debug.WriteLine("RowEnter:RowIndex=" + e.RowIndex);
    Debug.WriteLine("RowEnter:ColumnIndex=" + e.ColumnIndex);

    foreach (DataGridViewRow row in ((DataGridView)sender).SelectedRows) {
        string id = row.Cells[0].Value.ToString();
        Debug.WriteLine("selectRow!! id=" + id);
    }

}

引用返信 編集キー/
■25666 / inTopicNo.2)  Re[1]: datagridviewの選択行について
□投稿者/ カドルドエグ (33回)-(2008/09/24(Wed) 14:47:56)
No25660 (ありあり さん) に返信
>1行目を最初にクリックした場合のみ、SelectedRowsに行が格納されていない現象
データがバインドされた時点で1行目は既にフォーカスを受け取っています。
従って、フォームが表示された直後に1行目をクリックしても、フォーカスが変化しているわけではないので
そもそもRowEnterイベント自体が発生しません。

また、フォーカスがあたることと選択されていることは見た目は同じように見えますが、
実際は違うものなのでデータバインド後にClearSelection(DataGridView上の選択を全て解除)を行っても
フォーカス自体は変わりません。
かといってフォーカスを行のどこにも当たらないようにする、というのは不可能です。

なので、
RowEnterイベントではなく、SelectionChangedイベントを使用すると、純粋に「選択されたか否か」
で見るので上手く動いてくれるのではないでしょうか。
引用返信 編集キー/
■25674 / inTopicNo.3)  Re[2]: datagridviewの選択行について
□投稿者/ ありあり (5回)-(2008/09/24(Wed) 15:14:57)
No25666 (カドルドエグ さん) に返信
> ■No25660 (ありあり さん) に返信
> >1行目を最初にクリックした場合のみ、SelectedRowsに行が格納されていない現象
> データがバインドされた時点で1行目は既にフォーカスを受け取っています。
> 従って、フォームが表示された直後に1行目をクリックしても、フォーカスが変化しているわけではないので
> そもそもRowEnterイベント自体が発生しません。
>
> また、フォーカスがあたることと選択されていることは見た目は同じように見えますが、
> 実際は違うものなのでデータバインド後にClearSelection(DataGridView上の選択を全て解除)を行っても
> フォーカス自体は変わりません。
> かといってフォーカスを行のどこにも当たらないようにする、というのは不可能です。
>
> なので、
> RowEnterイベントではなく、SelectionChangedイベントを使用すると、純粋に「選択されたか否か」
> で見るので上手く動いてくれるのではないでしょうか。


すみません。説明が足りませんでした。
仕様で1行目の選択はselected = falseとし、未選択状態となっています。

そこで1行目をクリックするとRowEnterイベントが動きます。
   ↓
しかし、1行目の選択行がとれない。という現象です。

引用返信 編集キー/
■25675 / inTopicNo.4)  Re[3]: datagridviewの選択行について
□投稿者/ ロック (106回)-(2008/09/24(Wed) 15:23:59)
>そもそもRowEnterイベント自体が発生しません。
自分もそう思ったので、実験してみたのですがイベントは発生するんですよね
っで、同じソースでやってみましたが、現象は発生しませんでした
選択データの取得はSelectionModeに左右されたりするので
とりあえず、DataGridViewSelectionMode.FullRowSelectでやってみたのですが
(複数行選択も可能な状態)
最初に1行目を選択しても1行目のデータを取得できました。(もちろんRowEnter()内で)

>仕様で1行目の選択はselected = falseとし、未選択状態となっています。
これを入れても入れなくても同じでした。
何か他の設定(プロパティ値)とか別イベントが影響しているのでは?


参考URL
http://dobon.net/vb/dotnet/datagridview/selectedcells.html


ちなみに複数選択が不可ならば、CurrentRowを使ってみるという手もあるのですが
dataGridView.CurrentRow.Cells[0].Valueとか
#foreachしてるから複数選択ですよね。。。

引用返信 編集キー/
■25691 / inTopicNo.5)  Re[4]: datagridviewの選択行について
□投稿者/ カドルドエグ (34回)-(2008/09/24(Wed) 16:06:25)
>自分もそう思ったので、実験してみたのですがイベントは発生するんですよね
私がテストしたコードは以下の通りです。
「動かすためには?」ということで、掲示されたサンプルよりかなり変更してあります。
因みに環境は…
・VS2005
・フォーム上には単純にDataGridViewのみ
・BindingSourceもDataSetも無し。コード見るとわかりますが、その場でDataTable等の設定をしています。
・DataGridViewの設定
 AllowUserToAddRows = False
  AllowUserToDeleteRows = False
  SelectionMode = FullRowSelect
  MultiSelect = True(デフォルト)

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        DataTable table = new DataTable();
        private void Form1_Load(object sender, EventArgs e)
        {
            GetData();
            this.dataGridView1.DataSource = table;
            dataGridView1.ClearSelection();
        }

        private void GetData()
        {
            table.Columns.Add("C1");
            table.Columns.Add("C2");
            table.Columns.Add("C3");

            table.Rows.Add("AA", "BB", "CC");
            table.Rows.Add("DD", "EE", "FF");
            table.Rows.Add("GG", "HH", "II");
            table.Rows.Add("JJ", "KK", "LL");
        }

        private void dataGridView1_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0 || e.ColumnIndex < 0) return;

            StringBuilder builder = new StringBuilder();
            foreach (DataGridViewRow row in ((DataGridView)sender).SelectedRows)
            {
                string id = ((DataRowView)row.DataBoundItem).Row["C1"].ToString();//row.Cells[0].Value.ToString();
                builder.Append(id + ",");
            }

            MessageBox.Show("afterEnterValue = " + builder.ToString());
        }

        private void dataGridView1_SelectionChanged(object sender, EventArgs e)
        {
            if (((DataGridView)sender).SelectedRows.Count < 1) return;
            StringBuilder builder = new StringBuilder();
            foreach (DataGridViewRow row in ((DataGridView)sender).SelectedRows)
            {
                string id = ((DataRowView)row.DataBoundItem).Row["C1"].ToString();//row.Cells[0].Value.ToString();
                builder.Append(id + ",");
            }

            MessageBox.Show("selectedValue = " + builder.ToString());
        }
    }

このコード上では、DataGridViewのDataSourceが設定されたときにRowEnterとSelectionChangedイベントが数回(※)発生し、
表示直後に一行目をクリックしてもSelectionChangedイベントのみが反応することを確認しています。
但し、選択した行が1つしかない場合は表示直後の選択行が2行目以降であるとき、
複数であれば1行目が含まれていても反応します。
※行数かと思っていましたが、実際にはイベントの連鎖の回数でした。

この後、Shownイベントをはさめて細かくタイミングを調べてみたところ、
Shownイベントの直前にRowEnterイベントが発生しました。

もしかして、ロックさんの
>イベントは発生する
というのはこのことでしょうか??

引用返信 編集キー/
■25702 / inTopicNo.6)  Re[2]: datagridviewの選択行について
□投稿者/ ありあり (7回)-(2008/09/24(Wed) 16:54:51)
No25666 (カドルドエグ さん) に返信
> ■No25660 (ありあり さん) に返信
> >1行目を最初にクリックした場合のみ、SelectedRowsに行が格納されていない現象
> データがバインドされた時点で1行目は既にフォーカスを受け取っています。
> 従って、フォームが表示された直後に1行目をクリックしても、フォーカスが変化しているわけではないので
> そもそもRowEnterイベント自体が発生しません。
>
> また、フォーカスがあたることと選択されていることは見た目は同じように見えますが、
> 実際は違うものなのでデータバインド後にClearSelection(DataGridView上の選択を全て解除)を行っても
> フォーカス自体は変わりません。
> かといってフォーカスを行のどこにも当たらないようにする、というのは不可能です。
>
> なので、
> RowEnterイベントではなく、SelectionChangedイベントを使用すると、純粋に「選択されたか否か」
> で見るので上手く動いてくれるのではないでしょうか。


SelectionChangedイベントの使用でできました。
どうもありがとうございました。


解決済み
引用返信 編集キー/
■25704 / inTopicNo.7)  Re[3]: datagridviewの選択行について
□投稿者/ ロック (107回)-(2008/09/24(Wed) 17:06:34)
同じくVS2005 C# XPです。

全体をコピーして、やってみたのですが
>このコード上では、DataGridViewのDataSourceが設定されたときにRowEnterとSelectionChangedイベントが数回(※)発生し、
ここまでは同じで

>表示直後に一行目をクリックしてもSelectionChangedイベントのみが反応することを確認しています。
SelectionChangedではなく、afterEnterValueが表示されました(^^;あれ?
#Debug.WriteLineにしてみたら、両方発生してました。

ただコレだと、ありありさんの言う最初に1行目をクリックすると値を取得できないという
現象が再現しました。
そして、カドルドエグさんの処理(SelectionChanged)で1行目の値が取得できていました。

>というのはこのことでしょうか??
いえ、DataGridViewの1行目を選択した時です。


前の自分のソースでは、ボタン押下でデータを取得していましたが
データの読み込みをLoad()で行うように変更してみたら
SelectionChangedだけでRowEnterが発生しませんでした。
データを読み込む位置で変化していますね・・

ちょっと混乱してきました。
まとめれば良いのですが、混乱してまとめきれません、ごめんなさい。(あと時間の関係も(汗

#って、書き込むとしたら解決してましたね。
#まあ、そんな事もあったということで

解決済み
引用返信 編集キー/
■25718 / inTopicNo.8)  Re[4]: datagridviewの選択行について
□投稿者/ カドルドエグ (35回)-(2008/09/24(Wed) 21:16:58)
No25704 (ロック さん) に返信
> 前の自分のソースでは、ボタン押下でデータを取得していましたが
なるほど。ボタンを使用していたのですね。
ハナっから「Loadでデータ取得」と思いこんでいました…;


既に解決済みですが、
こちらで時間ができ、ロックさんとほぼ同じ状況下でのテストが
できたので勝手にまとめてみます^^;

結論から書くと、
「データバインド完了直後にDataGridView本体にフォーカスが当たっているか」
ではないかと考えています。

というのも、ボタン押下でデータを取得した後のフォーカスは、
強制的に処理(dataGridView1.Select()など)を入れない限りはボタンのままです。

その結果、ボタン→DataGridView→DataGridView内の行(RowEnter発生)
となったのでしょう。
フォーカスについてはよく調べていませんが、恐らくDataGridView本体とその内部の行では
フォーカスは別物扱いなんだと思います。

なので、
データ取得のタイミングがLoadであれボタン押下であれ、
取得後のフォーカスがDataGridViewならば1行目を最初にクリックしてもRowEnterは発生せず、
他のコントロールならば発生する、ということかなと。

今回、私の場合はLoadでデータ取得 + フォームにはDataGridView1つだけ
= 取得後のフォーカスは必然的にDataGridView
だったのでRowEnterイベントは発生しなかったのだと考えています。

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


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

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -