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

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

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

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

Q&A

解決済

1回答

219閲覧

[VB.NET] 無効化されたDataGridViewボタンセルのClickイベントが上がらないようにしたい

teretail

総合スコア23

VB.NET

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

0グッド

0クリップ

投稿2025/05/30 04:42

実現したいこと

DataGridView コントロールのボタン列のボタンを無効にする
こちらのサイトを参考にDataGridViewButtonColumnのカスタムコントロールを作成しました。

ここで紹介されているソースは見た目を変更するだけなので、無効化されたボタンをクリックしてもCellClickイベントやCellContentClickイベントは発生してしまいます。
イベント発生時に都度ボタンの状態を確認して無効ならば処理をしないという手もありますが、
そもそもイベントが上がらないようにできないかと考えました。

発生している問題・分からないこと

OnClickとOnContentClickをオーバーライドし、ボタンが有効な場合のみ基底クラスのメソッドを呼ぶようにしました。
これによってイベントが上がらなくなると踏んでいましたが、CellClickイベントやCellContentClickイベントは上がってしまいました。

該当のソースコード

VBNET

1Public Class DataGridViewDisableButtonColumn 2 Inherits DataGridViewButtonColumn 3 4 Public Sub New() 5 Me.CellTemplate = New DataGridViewDisableButtonCell 6 End Sub 7 8End Class 9 10Public Class DataGridViewDisableButtonCell 11 Inherits DataGridViewButtonCell 12 13 Private _enabled As Boolean 14 15 Public Property Enabled() As Boolean 16 Get 17 Return _enabled 18 End Get 19 Set(ByVal value As Boolean) 20 _enabled = value 21 End Set 22 End Property 23 24 ' Override the Clone method so that the Enabled property is copied. 25 Public Overrides Function Clone() As Object 26 Dim cell As DataGridViewDisableButtonCell = CType(MyBase.Clone(), DataGridViewDisableButtonCell) 27 Return cell 28 End Function 29 30 ' By default, enable the button cell. 31 Public Sub New() 32 Me._enabled = True 33 End Sub 34 35 Protected Overrides Sub Paint( 36 ByVal graphics As System.Drawing.Graphics, ByVal clipBounds As System.Drawing.Rectangle, ByVal cellBounds As System.Drawing.Rectangle, 37 ByVal rowIndex As Integer, ByVal elementState As System.Windows.Forms.DataGridViewElementStates, 38 ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, 39 ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal advancedBorderStyle As System.Windows.Forms.DataGridViewAdvancedBorderStyle, 40 ByVal paintParts As System.Windows.Forms.DataGridViewPaintParts 41 ) 42 If (Me._enabled) Then 43 ' The button cell is enabled, so let the base class handle the painting. 44 MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts) 45 46 Else 47 ' The button cell is disabled, so paint the border, 48 ' background, and disabled button for the cell. 49 50 ' Draw the cell background, if specified. 51 If (paintParts And DataGridViewPaintParts.Background = DataGridViewPaintParts.Background) Then 52 Dim cellBackground As SolidBrush = New SolidBrush(cellStyle.BackColor) 53 54 graphics.FillRectangle(cellBackground, cellBounds) 55 cellBackground.Dispose() 56 End If 57 58 ' Draw the cell borders, if specified. 59 If (paintParts And DataGridViewPaintParts.Border = DataGridViewPaintParts.Border) Then 60 PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle) 61 End If 62 63 ' Calculate the area in which to draw the button. 64 Dim buttonArea As Rectangle = cellBounds 65 Dim buttonAdjustment As Rectangle = Me.BorderWidths(advancedBorderStyle) 66 buttonArea.X = buttonArea.X + buttonAdjustment.X 67 buttonArea.Y = buttonArea.Y + buttonAdjustment.Y 68 buttonArea.Height = buttonArea.Height - buttonAdjustment.Height 69 buttonArea.Width = buttonArea.Width - buttonAdjustment.Width 70 71 ' Draw the disabled button. 72 ButtonRenderer.DrawButton(graphics, buttonArea, VisualStyles.PushButtonState.Disabled) 73 74 ' Draw the disabled button text. 75 If (Me.FormattedValue.GetType Is GetType(String)) Then 76 TextRenderer.DrawText(graphics, Me.FormattedValue.ToString, Me.DataGridView.Font, buttonArea, SystemColors.GrayText) 77 End If 78 End If 79 End Sub 80 81 Protected Overrides Sub OnClick(e As DataGridViewCellEventArgs) 82 If (Me._enabled) Then 83 MyBase.OnClick(e) 84 End If 85 End Sub 86 87 Protected Overrides Sub OnContentClick(e As DataGridViewCellEventArgs) 88 If (Me._enabled) Then 89 MyBase.OnContentClick(e) 90 End If 91 End Sub 92 93End Class

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

Google等で検索すると通常のButtonの例は出てきます。
Buttonのカスタムコントロールを作成した上で、上記と同様にOnClickをオーバーライドし、基底クラスのOnClickを呼ばないようにしたところ、こちらは期待通りにClickイベントが上がりませんでした。

そもそもオーバーライドしたOnClickはDataGridViewButtonCellのものなので、DataGridViewのCellClick/CellContentClickは止められないということでしょうか?

補足

開発環境:
Microsoft Visual Studio Enterprise 2015(Version 14.0.25431.01 Update 3)
Microsoft .NET Framework(Version 4.8.09037)

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

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

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

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

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

guest

回答1

0

ベストアンサー

そもそもオーバーライドしたOnClickはDataGridViewButtonCellのものなので、DataGridViewのCellClick/CellContentClickは止められないということでしょうか?

DataGridViewButtonCell のソースを見ると、DataGridViewButtonColumn(DataGridViewCell) の OnCellClick メソッドは DataGridView の OnCellClick メソッドから呼ばれているので、DataGridViewButtonColumn のみで解決するのは難しそうです。
https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/DataGridViewMethods.cs,d5fd6e0c66ee6656

DataGridView を継承して対応しましょう。

vb

1Public Class DataGridViewEx 2 Inherits DataGridView 3 4 Public Overridable Function GetDataGridViewCell(e As DataGridViewCellEventArgs) As DataGridViewCell 5 If e.RowIndex >= 0 Then 6 Dim dataGridViewRow As DataGridViewRow = Me.Rows.SharedRow(e.RowIndex) 7 If e.ColumnIndex >= 0 Then 8 Return dataGridViewRow.Cells(e.ColumnIndex) 9 Else 10 Return dataGridViewRow.HeaderCell 11 End If 12 Else 13 If e.ColumnIndex >= 0 Then 14 Return Me.Columns(e.ColumnIndex).HeaderCell 15 Else 16 Return Me.TopLeftHeaderCell 17 End If 18 End If 19 End Function 20 21 Protected Overrides Sub OnCellClick(e As DataGridViewCellEventArgs) 22 Dim buttonCell As DataGridViewDisableButtonCell = 23 TryCast(GetDataGridViewCell(e), DataGridViewDisableButtonCell) 24 If buttonCell IsNot Nothing Then 25 If buttonCell.Enabled Then 26 MyBase.OnCellClick(e) 27 End If 28 Else 29 MyBase.OnCellClick(e) 30 End If 31 End Sub 32 33 Protected Overrides Sub OnCellContentClick(e As DataGridViewCellEventArgs) 34 Dim buttonCell As DataGridViewDisableButtonCell = 35 TryCast(GetDataGridViewCell(e), DataGridViewDisableButtonCell) 36 If buttonCell IsNot Nothing Then 37 If buttonCell.Enabled Then 38 MyBase.OnCellContentClick(e) 39 End If 40 Else 41 MyBase.OnCellContentClick(e) 42 End If 43 End Sub 44 45End Class

余談ですが、私は DataGridView を素で使うことはしません。必ず継承して使います。

理由は
・ダブルバッファが有効でない
・ComboBox や CheckBox を変更したら値を反映したい
・描画抑止の機能がない
・複数セルへ貼り付けできない
などです。

投稿2025/06/01 17:59

KOZ6.0

総合スコア2730

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

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

teretail

2025/06/03 09:19

やはりDataGridViewも継承しないと解決できないのですね・・・ ご提示いただいたソースで試したところ期待通りCellClickイベント、CellContentClickイベントが上がらないことを確認できました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問