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

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

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

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

Q&A

解決済

4回答

4600閲覧

DataGridViewでのボタンカラムについて

gorota

総合スコア25

VB.NET

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

0グッド

2クリップ

投稿2015/05/07 04:57

編集2015/05/07 04:59

![イメージ説明]WIDTH:456
DataGridViewでの
ボタンカラム(DataGridViewButtonColumn)を配置して
検索用ボタンとして利用したいのですが、
クリックするとValidationが発生してしまいます
なんとか、
セル単位で CausesValidation=False に設定出来ないでしょうか?
(DataGridView.CellValidatingで状態のチェック行ってので
ボタンクリックはスキップしたい)

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

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

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

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

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

guest

回答4

0

少し検証してみましたが、DataGridViewの処理の流れからすると、
前セルの検証 → セル選択状態の解除 → 次セルの選択 → クリックとかEnterとかの処理
という流れのようなのでCellValidating時点でどこを押されたか判定するのはおそらく難しいでしょう。

マウスクリックのみを前提とするのであればMouseEnterとMouseLeaveで選択候補のセル位置を保持しておきCellValidating時に判定することは出来そうです。

lang

1Public Class DataGridViewEx 2 Inherits DataGridView 3 4#Region "クリックするかも?情報" 5 Private surukamoRow As Integer? = Nothing 6 Private surukamoColumn As Integer? = Nothing 7 8 Protected Overrides Sub OnCellMouseEnter(e As DataGridViewCellEventArgs) 9 MyBase.OnCellMouseEnter(e) 10 surukamoRow = e.RowIndex 11 surukamoColumn = e.ColumnIndex 12 End Sub 13 14 Protected Overrides Sub OnCellMouseLeave(e As DataGridViewCellEventArgs) 15 MyBase.OnCellMouseLeave(e) 16 surukamoRow = Nothing 17 surukamoColumn = Nothing 18 End Sub 19#End Region 20 21 Protected Overrides Sub OnCellValidating(e As DataGridViewCellValidatingEventArgs) 22 '押下したものがボタンである場合、CellValidatingスキップ 23 If surukamoRow.HasValue And surukamoColumn.HasValue Then 24 Dim clickCell = Me.Rows(surukamoRow.Value).Cells(surukamoColumn.Value) 25 If TypeOf clickCell Is DataGridViewButtonCell Then 26 Return 27 End If 28 End If 29 MyBase.OnCellValidating(e) 30 End Sub 31End Class

が、泥臭いですね。こういうことをやると後々の問題に繋がったりします。
なぜボタン押下時はCellValidatingを回避するのかという目的に回帰し、
代替案を検討する方向をお薦めします…。

投稿2015/05/08 12:08

Tak1wa

総合スコア4791

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

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

0

自己解決

Tak1wa さんのご指摘通り
原点の戻って自分で考えて見ます
派生クラスであまり特殊なケースを記述すると
修正保守が発生した時に面倒ですし、
構文はより単純な方が優秀ですから.....
解決すれば、再度UPします

投稿2015/05/08 13:06

gorota

総合スコア25

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

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

0

gorotaさんの要件を満たせなかったようなので次点の案を提示します。
DataGridViewButtonCellの派生クラスを定義し、ひたすらイベントをオーバーライドする方法です。

lang

1Public Class DataGridViewButtonCellEx 2 Inherits DataGridViewButtonCell 3 4 Public Property CausesValidation As Boolean 5 6 Protected Overrides Sub OnClick(e As DataGridViewCellEventArgs) 7 Me.DoEvent(AddressOf MyBase.OnClick, e) 8 End Sub 9 10 Protected Overrides Sub OnContentClick(e As DataGridViewCellEventArgs) 11 Me.DoEvent(AddressOf MyBase.OnContentClick, e) 12 End Sub 13 14 Protected Overrides Sub OnContentDoubleClick(e As DataGridViewCellEventArgs) 15 Me.DoEvent(AddressOf MyBase.OnContentDoubleClick, e) 16 End Sub 17 18 Protected Overrides Sub OnDoubleClick(e As DataGridViewCellEventArgs) 19 Me.DoEvent(AddressOf MyBase.OnDoubleClick, e) 20 End Sub 21 22 Protected Overrides Sub OnKeyDown(e As KeyEventArgs, rowIndex As Integer) 23 Me.DoEvent(AddressOf MyBase.OnKeyDown, e, rowIndex) 24 End Sub 25 26 Protected Overrides Sub OnKeyPress(e As KeyPressEventArgs, rowIndex As Integer) 27 Me.DoEvent(AddressOf MyBase.OnKeyPress, e, rowIndex) 28 End Sub 29 30 Protected Overrides Sub OnKeyUp(e As KeyEventArgs, rowIndex As Integer) 31 Me.DoEvent(AddressOf MyBase.OnKeyUp, e, rowIndex) 32 End Sub 33 34 Protected Overrides Sub OnMouseClick(e As DataGridViewCellMouseEventArgs) 35 Me.DoEvent(AddressOf MyBase.OnMouseClick, e) 36 End Sub 37 38 Protected Overrides Sub OnMouseDoubleClick(e As DataGridViewCellMouseEventArgs) 39 Me.DoEvent(AddressOf MyBase.OnMouseDoubleClick, e) 40 End Sub 41 42 Protected Overrides Sub OnMouseDown(e As DataGridViewCellMouseEventArgs) 43 Me.DoEvent(AddressOf MyBase.OnMouseDown, e) 44 End Sub 45 46 Protected Overrides Sub OnMouseMove(e As DataGridViewCellMouseEventArgs) 47 Me.DoEvent(AddressOf MyBase.OnMouseMove, e) 48 End Sub 49 50 Protected Overrides Sub OnMouseUp(e As DataGridViewCellMouseEventArgs) 51 Me.DoEvent(AddressOf MyBase.OnMouseUp, e) 52 End Sub 53 54 Private Sub DoEvent(Of T As EventArgs)(ByVal raisingEvent As Action(Of T), ByVal e As T) 55 Dim baseCausesValidation As Boolean = 56 MyBase.DataGridView.CausesValidation 57 58 MyBase.DataGridView.CausesValidation = Me.CausesValidation 59 raisingEvent(e) 60 MyBase.DataGridView.CausesValidation = baseCausesValidation 61 End Sub 62 63 Private Sub DoEvent(Of T As EventArgs)(ByVal raisingEvent As Action(Of T, Integer), ByVal e As T, ByVal index As Integer) 64 Dim baseCausesValidation As Boolean = 65 MyBase.DataGridView.CausesValidation 66 67 MyBase.DataGridView.CausesValidation = Me.CausesValidation 68 raisingEvent(e, index) 69 MyBase.DataGridView.CausesValidation = baseCausesValidation 70 End Sub 71End Class

※ただの案であり、動作未検証です。

投稿2015/05/07 13:21

htsign

総合スコア870

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

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

gorota

2015/05/07 23:22

htsignさん お手数をおかけします 上記のように DataGridViewButtonCellの派生クラスというよりは 親のDataGridViewの派生クラスで Protected Overrides Sub OnCellLeave とか  Protected Overrides SubOnCellLeave で Validating を発生させている 次コートロールがセル上のボタンであれば MyBase の処理に渡さないとかが出来ないか考えています
htsign

2015/05/08 01:18

ボタンをセルに配置する段階でDataGridViewButtonCellExクラスののインスタンスを置いておけばお望みの動作になるかと考えたのですが…これも駄目でしたか…。 固定で「次の行」でいいのであれば、普通にCellValidatingのe.ColumnIndexに+1するのでは駄目ですか?
guest

0

質問の回答にはなっていませんが、CellValidatingイベントハンドラ内に

lang

1Dim self = DirectCast(sender, DataGridView) 2Dim clicked As DataGridViewCell = self(e.ColumnIndex, e.RowIndex) 3 4If TypeOf clicked Is DataGridViewButtonCell Then Return

を挟むというのはどうでしょうか。

投稿2015/05/07 07:42

htsign

総合スコア870

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

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

gorota

2015/05/07 10:25

ありがとうございます 只、上記のコードですと CellValidating で補足されるのは ボタンセルをクリックして発生するのは 前の位置にあるコードで、 正に、これがまずいのです
Tak1wa

2015/05/07 11:59

こんにちは。 私もhtsignさんの案が一番シンプルで良さそうだなと思っていたのですが、 問題点を理解出来ていなかったかもしれません。 「CellValidating→CellContentClickの順で発生すると都合が悪いのでボタンセルクリック時はCellValidatingをスキップしたい」と解釈していたのですが異なりますか? また、コメント内の「前の位置にあるコード」とは何を指していますでしょうか。
gorota

2015/05/07 23:11

興味を示して頂いて有難うございます 「前の位置にあるコード」とは 画面画像で検索ボタンの左側にあるコード欄のことで ここのフォーカスがある状態で検索ボタンを押すと CellValidatingで捕捉されるセル位置は コード欄という事です
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問