質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

2回答

3341閲覧

datagridview checkboxの値取得時の動作差異について

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2017/06/16 01:55

編集2017/06/16 13:48

お世話になります。

現在、windowsformアプリケーションのdatagridviewにあるチェックボックスからチェック値を取得するコードを書いています。
ここで、不明な点が2点あるのでご質問させていただきました。

1 Button.click イベントから発生させると値が取得できる。
2 ToolStripMenuItem.click イベントから発生させると値が取得できない。

同コードを呼び出しているのに動作に差異が発生する原因がわかりません。
ご教授よろしくお願いします。コードは以下になります。

C#

1 private Func<DataGridView, IEnumerable<DataGridViewRow>> FileTarget = 2 (DataGridView c) => c.Rows.Cast<DataGridViewRow>().Where(n => (bool)n.Cells[0].Value== true);

vb

1vb.net 2 3Private FileTarget As Func(Of DataGridView, IEnumerable(Of DataGridViewRow)) = 4 Function(c) c.Rows.Cast(Of DataGridViewRow).Where(Function(d) CBool(d.Cells(0).Value) = True) 5

追記)
本来ならdatagridview内のcheckboxの値はtrue,false なのですが、2の場合のみnull,nothingとなります。
そして、キャスト失敗時のエラーが発生します。

追記2)
datagridviewに関してですが、基本はSQLの結果を表示する、参照画面として使用しています。
又、checkBox以外は全てreadOnely= trueにしており、新規追加、編集はできません。

その他設定プロパティ
.DataGridViewSelectionMode.FullRowSelect
.MultiSelect = False
.Resizable = DataGridViewTriState.False
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False

後、色々と試してみたのですが、同form上のdatagridviewと、ToolStripMenuItem以外をアクティブにすると2 でも結果が取得できました。
原因は不明です。

追記3)
どちらも foreach(DataGridViewRow test in FileTarget(targetGridview))として使用しています。

追記4)
datagridview内にデータを挿入するのは起動時のloadイベント時となります。
test sorce

c#

1 public Form1() 2 { 3 InitializeComponent(); 4 5 dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn()); 6 dataGridView1.Columns.Add("a","a"); 7 dataGridView1.Columns.Add("b", "b"); 8 dataGridView1.Columns.Add("c","c"); 9 dataGridView1.Columns.Add("d", "d"); 10 dataGridView1.Rows.Add(false, "1", "1", "1"); 11 dataGridView1.Rows.Add(false, "2", "2", "2"); 12 dataGridView1.Rows.Add(false, "3", "3", "3"); 13 dataGridView1.Rows.Add(false, "4", "4", "4"); 14 dataGridView1.Rows.Add(false, "5", "5", "5"); 15 dataGridView1.Rows.Add(false, "6", "6", "6"); 16 17 18 dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect; 19 20 dataGridView1.MultiSelect = false; 21 dataGridView1.Rows[0].Resizable = DataGridViewTriState.False; 22 dataGridView1.AllowUserToAddRows = false; 23 dataGridView1.AllowUserToDeleteRows = false; 24 dataGridView1.AllowUserToAddRows = false; 25 dataGridView1.AllowUserToDeleteRows = false; 26 dataGridView1.RowHeadersVisible = false; 27 28 } 29 30 31 private Func<DataGridView, IEnumerable<DataGridViewRow>> FileTarget = 32 (DataGridView c) => c.Rows.Cast<DataGridViewRow>().Where(n => (bool)n.Cells[0].Value == true); 33 34 private void button1_Click(object sender, EventArgs e) 35 { 36 foreach (DataGridViewRow d in FileTarget(dataGridView1)) 37 { 38 //内部へ入る 39 MessageBox.Show((string)d.Cells[1].Value) ; 40 41 }; 42 43 } 44 45 private void test1ToolStripMenuItem_Click(object sender, EventArgs e) 46 { 47 48 foreach (DataGridViewRow d in FileTarget(dataGridView1)) 49 { 50 //内部へ入らない 51 MessageBox.Show((string)d.Cells[1].Value); 52 53 }; 54 55 } 56 57 58

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ebiryo

2017/06/16 02:48

「値が取得できない」というのはどういう意味でしょうか?結果が正しくない?例外がthrowされる?
退会済みユーザー

退会済みユーザー

2017/06/16 03:00

checkboxの結果値に1の場合,true,falseが入り、2の場合null又は、nothingが入ります、
YAmaGNZ

2017/06/16 09:34

FileTargetを呼び出しているコードはないのでしょうか?また、ButtanイベントやMeinStripイベントとは何なのでしょうか?
退会済みユーザー

退会済みユーザー

2017/06/16 11:58

回答ありがとうございます。追記しました。
YAmaGNZ

2017/06/16 12:13

こちらでFormにDataGridView、Button、menuStripにToolStripMenuItemを1つ配置した状態でButtonのクリックイベント、ToolStripMenuItemのクリックイベントで呼び出してみましたがチェックした行は取得できています。値が取得できないというのは、foreachループ内が全く実行されず、FileTargetが1行も取得してない状態のことでしょうか?できれば、DataGridViewにデータが格納されるタイミング等が回答者が判断できるようなソースを提示できないでしょうか?
退会済みユーザー

退会済みユーザー

2017/06/16 13:02

簡易的なテストソースを追記しました。自分は取得できないですね・・・。恐縮ですが、至らぬ点などがあれば、ご回答よろしくお願いします。
guest

回答2

0

ベストアンサー

MenuStripをクリック時にフォーカスの移動が行われません。
そのためDataGridViewのチェックボックスの編集状態が終了しておらず値が確定していないのではないでしょうか。
複数チェックし、MenuStripをクリックした場合は取得できています。

ボタンをクリックした場合は、ボタンがフォーカスを持つので、DataGridViewは編集状態が終了します。
ここで値が確定するので、取得できるようになります。

私が実験した時は、初期の値としてチェックを付けた行を用意していたので分かりませんでした。

投稿2017/06/16 13:48

編集2017/06/16 13:56
YAmaGNZ

総合スコア10222

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/06/16 13:56

ご回答ありがとうございます。自己解決したとぬか喜びしていましたが、やっぱり無理でした。 ただ、不思議なのがMenustripクリック時のフォーカス移動はイベントに反映されないのかが気になるところです。
YAmaGNZ

2017/06/16 14:31

クリックした時、フォーカスを移動するコントロールと移動しないコントロールがあります。 ToolStripはフォーカスを移動しないコントロールにあたります。 このようなコントロールがあるので、DataGridViewのほうでチェックボックスの値変更時に編集を確定させるようにするか ToolStripのクリック側で値を確定させるかすればよいかと思います。
退会済みユーザー

退会済みユーザー

2017/06/16 15:08

フォーカスが移動しないコントロールですがmsdnなどに記入してあるのでしょうか? 不躾なご質問ばかりで申し訳ありませんがよろしければお教えください。
YAmaGNZ

2017/06/16 16:21 編集

私の経験での話なので、どこかに記述してある文章があるかは分かりません。 今回の場合ですと、ToolStripItemはSystem.Windows.Forms.ControlではなくSystem.ComponentModel.Componentの継承なので フォーカス関連のプロパティ、メソッドがありません。 (ただ、System.Windows.Forms.Controlを継承していてもクリック時にはフォーカスが移動しないコントロールも存在するようです。PictureBoxはSystem.Windows.Forms.Controlを継承していますが、クリックイベント発生時にはフォーカス移動しません) DataGridViewでのチェックボックスの場合、編集モードかどうかは判別しにくいため CurrentCellDirtyStateChangedイベントでCommitEditを呼ぶなどして編集を確定させてしまうのが よいと思います。
退会済みユーザー

退会済みユーザー

2017/06/17 00:27 編集

継承関係までは見ていませんでした。次回からは継承関連も頭に入れて動作を検証しようと思います。 質問にまでご回答ありがとうございました。
YAmaGNZ

2017/06/17 00:56

注意点です。 CurrentCellDirtyStateChangedイベントでCommitEditを呼ぶと、編集途中でも変更が確定します。 今回のようなチェックボックスなら問題はないのですが、テキストの編集の場合は、テキストが変更されると イベントが発生して編集中のデータが確定してしまいます。 この為、ESCキーなどでキャンセルしようとしても編集前の状態に戻せなくなります。 ですので、無条件に呼び出すと問題がある場合があります。
退会済みユーザー

退会済みユーザー

2017/06/17 01:13 編集

ご忠告ありがとうございます。 Button.click イベント、ToolStripMenuItem.clickイベント発生時のforeach 文の直前にCommitEditを入れさせてもらいました。 今回はreadonly = true にしてますので、問題ないと思われます。 以後、使用時に注意します。
ebiryo

2017/06/17 02:31

私も勉強になりました。ありがとうございました。
guest

0

的外れだったらゴメンなさい。

1と2でそれぞれFileTarget を実行するとき、対象となるDataGridView の属性などは変えていないですよね?

たとえば DataGridViewの「追加を有効にする(AllowUserToAddRows)」が true だと、FileTargetは例外がthrow されますが。

投稿2017/06/16 04:28

ebiryo

総合スコア797

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/06/16 04:54

解答ありがとうございます。 datagridviewの詳細を追記しました。基本的に参照画面として使用しているので追加は禁止しています。
ebiryo

2017/06/16 09:54

Buttan⇒Button, MeinStrip⇒MenuStrip のタイポですよね? YAmaGNZさんが仰るとおりFileTargetを実行している箇所のソースを見せていただいたほうが早い気がします。
退会済みユーザー

退会済みユーザー

2017/06/16 11:59

誤字を修正しました。
ebiryo

2017/06/16 15:48 編集

YAmaGNZさんの仰るとおり、編集モードが解除されていないのだと思います test1ToolStripMenuItem_Clickのforeahの前に以下を実行するとどうでしょう? dataGridView1.EndEdit();
退会済みユーザー

退会済みユーザー

2017/06/17 00:34

ebiryo 様、YAmaGNZ様の仰る通りに、 dataGridView1.EndEdit(); を実行すると取得できました。 長々と解決まで付き合って頂き、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問