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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

コンボボックス

GUIの要素のひとつです。Listboxと同様にいくつかのうちひとつを選択する機能だが、Comboboxの場合は選択されたもののみがデフォルトとして表示される。

継承

継承(インヘリタンス)はオブジェクト指向プログラミングに存在するシステムです。継承はオブジェクトが各自定義する必要をなくし、継承元のオブジェクトで定義されている内容を引き継ぎます。

VB.NET

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

Q&A

解決済

1回答

1421閲覧

WindowsFormのカスタムコンボボックスに使用した内部コントロールの継承イベントを実装したい

ashitani

総合スコア1

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

コンボボックス

GUIの要素のひとつです。Listboxと同様にいくつかのうちひとつを選択する機能だが、Comboboxの場合は選択されたもののみがデフォルトとして表示される。

継承

継承(インヘリタンス)はオブジェクト指向プログラミングに存在するシステムです。継承はオブジェクトが各自定義する必要をなくし、継承元のオブジェクトで定義されている内容を引き継ぎます。

VB.NET

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

0グッド

0クリップ

投稿2023/01/29 09:56

前提

VB.NETで内部にチェックボックス付リストボックスを保持したコンボボックスを作成しました

実現したいこと

WindowsFormのカスタムコンボボックスに使用した内部コントロールの継承イベントを実装したい

こちらのサイトを参考にチェックボックス付コンボボックスを作成しました。
https://hilapon.hatenadiary.org/entry/20100406/1270552723

文字数制限で自身のソースが記述出来ませんでしたので、参考リンクのソースを見て頂ければ幸いです。

そのクラスはCheckedComboBoxというクラスでComboBoxを継承して作成されています。
ドロップダウンを展開すると内部のコントロールであるCheckedListBoxが表示されリストの左側のチェックが可能、ドロップダウンを閉じるとコンボボックスのテキストにリストでチェックした内容が表示されるという機能です。

上記コンボボックスを業務別に幾つかのパターンで作成する必要があるためそれを継承してCustomCheckedComboBoxを作成しました。(コードの下方に記述)

継承先のCustomCheckedComboBoxにおいて、継承元のコントロールの内部にあるCustomCheckedListBoxのOnDrawItemイベントをOverridesしたイベントを作成したいのですが、継承先にどのように実装すれば良いか分かりません。
上記のような内部に配置されたコントロールのイベントを継承するにはどのような実装が必要でしょうか?

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

VB.NET

1 2’ 参照元のソースCheckedComboBoxを継承したコントロール 3Public Class CustomCheckedComboBox 4 Inherits CheckedComboBox 5 6#Region "コンストラクタ" 7 ''' <summary> 8 ''' コンストラクタ 9 ''' </summary> 10 ''' <remarks></remarks> 11 Public Sub New() 12 MyBase.New() 13 InitializeComponent() 14 End Sub 15#End Region 16 17#Region "InitializeComponent() : コンポーネント初期化" 18 ''' <summary> 19 ''' InitializeComponent 20 ''' </summary> 21 ''' <remarks></remarks> 22 Private Sub InitializeComponent() 23 Me.SuspendLayout() 24 25 ' このクラスでの読字の初期化処理があれば記述 26 27 Me.ResumeLayout(False) 28 Me.PerformLayout() 29 End Sub 30#End Region 31 32#Region "イベント" 33 34' 継承元のコントロールの内部にあるCustomCheckedListBoxのOnDrawItemイベントをOverridesしたイベントをここに記述したい 35 36#End Region 37 38End Class 39

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

VisualStudio2017 .NET Framework4.6.2
WindowsForm

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

CheckedComboBox を書き換えないと無理っぽいです。

(1) CheckedListBox の DrawItem イベントは無効にされているので、新しく実装します。

CheckedComboBox.CheckedComboBoxDropdown.CustomCheckedListBox クラスに以下のコードを追加

vb

1 Protected Overrides Sub OnDrawItem(e As DrawItemEventArgs) 2 MyBase.OnDrawItem(e) 3 RaiseEvent DrawItem(Me, e) 4 End Sub 5 6 Public Shadows Event DrawItem As DrawItemEventHandler

(2) CheckedComboBox.CheckedComboBoxDropdown クラスで、(1) のイベントをフックします。

コンストラクタに AddHander を追加

vb

1 Public Sub New(ByVal parent As CheckedComboBox) 2 Me.m_parent = parent 3 Me.InitializeComponent() 4 Me.ShowInTaskbar = False 5 ' イベントハンドラを設定します。 6 AddHandler Me.m_cclb.ItemCheck, AddressOf Me.m_cclb_ItemCheck 7 AddHandler Me.m_cclb.DrawItem, AddressOf Me.m_cclb_DrawItem '← これを追加 8 End Sub

(3) (2) のメソッドから親の OnDrawItem メソッドを呼び出します。

vb

1 Private Sub m_cclb_DrawItem(sender As Object, e As DrawItemEventArgs) 2 m_parent.OnDrawItem(e) 3 End Sub

こうすると、DrawItem イベントが発生します。

投稿2023/01/29 13:35

KOZ6.0

総合スコア2626

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

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

ashitani

2023/01/29 14:20

KOZ6.0さん 回答ありがとうございます! ご教示の通りCheckedComboBoxクラスとその配下に実装しました。 投稿のコードに記述した通り、CheckedComboBoxを継承したCustomCheckedComboBoxクラスで上記のフックしたイベントをOverridesしたイベントを記述するにはどうなりますでしょうか?
KOZ6.0

2023/01/29 14:35

OnDrawItem メソッドをオーバーライドするだけです
ashitani

2023/01/29 16:23

KOZ6.0さん、ありがとうございます! そうですね、少し頭が整理出来ていませんでした。 内部のコントロールであるチェックボックス付リストボックスのテキストをカスタマイズして描画したかったのですが、無事にそのコードは実行されました。 厚かましく少し追加で質問したいのですが、OnDrawItem メソッドをオーバーライドしたコードでチェックボックス付リストボックスのテキストの描画を行った結果、リストの各行のチェックボックスが消えてしまいました。 せっかくのチェックボックス付リストボックスをドロップダウンに使用した意味が無くなってしまいました。 こううい場合はチェックボックスも自分で描画し直す必要がありますでしょうか? 試しに下記コードで1列目のテキストのLeftを少し右にずらした位置にしても空間が出来るだけで結果は同じでチェックボックスは表示されませんでした。 Protected Overrides Sub OnDrawItem(e As DrawItemEventArgs) MyBase.OnDrawItem(e) e.DrawBackground() Dim penLine As Drawing.Pen = New Drawing.Pen(Drawing.SystemColors.ControlDark) Dim borderLeft As Single = 188.0F Dim rectBounds As Drawing.Rectangle = e.Bounds Dim comboText As String = String.Empty Dim foreColor As Drawing.Color = e.ForeColor '境界線を描画 e.Graphics.DrawLine(penLine, borderLeft, e.Bounds.Top, borderLeft, e.Bounds.Bottom) ' 1列目描画 comboText = "テスト文字列" rectBounds.X += 2 TextRenderer.DrawText(e.Graphics, comboText, e.Font, rectBounds, foreColor, TextFormatFlags.NoPadding) ' 上記と同様に2列目描画 e.DrawFocusRectangle() End Sub
KOZ6.0

2023/01/29 18:36

+2 では足りません。 チェックボックスの大きさぶん右にずらしてください。
KOZ6.0

2023/01/29 18:49 編集

あ、e.DrawBackground() で塗りつぶしちゃってますね。 チェックボックスを除いた範囲を塗りつぶすようにしないとだめです。 MyBase.OnDrawItem(e) Dim comboText = "テスト文字列" Dim rectBounds As Rectangle = e.Bounds Const checkBoxSize = 18 rectBounds.X += checkBoxSize rectBounds.Width -= checkBoxSize Using b As New SolidBrush(BackColor) e.Graphics.FillRectangle(b, rectBounds) End Using TextRenderer.DrawText(e.Graphics, comboText, e.Font, rectBounds, ForeColor, TextFormatFlags.NoPadding) e.DrawFocusRectangle()
ashitani

2023/01/29 19:21

KOZ6.0さん、ありがとうございます! この時間帯に作業進めていたので、回答頂けてめちゃくちゃ有難いです。 以前に複数列のコンボボックスの要件がありその時はオーナードロー部分を別のプログラマさんに依頼しました。 今回は複数行選択可能なチェックボックス付コンボボックスの提供をすることになり、自分でやってみましたが該当箇所のコードの理解が足らず苦戦していましたので大変助かりました。 教えて頂いた通りにしたところ、展開したチェックボックス付コンボボックスで任意の行にマウスオーバーさせたところ、その行が白くなってテキストが判別出来なくなってしまいました。 上記コードのUsing ~ End Usingをコメントアウトしてみたところ、解消されました。 重ねてお礼申し上げます。 大変助かりました。ありがとうございました。
KOZ6.0

2023/01/29 19:51

>上記コードのUsing ~ End Usingをコメントアウトしてみたところ、解消されました。 それはおかしいです。何か処理を入れてないですか?
ashitani

2023/01/29 20:12

現在のコードです。 確かに、Using ~ End Usingをコメントアウトすると元々チェックリストボックスに描画されている文字が隠れていない気がします。試しにチェックボックスの幅を大きくすると下の文字がずれて見えますので。 逆にUsing ~ End Usingを生かすとマウスオーバー時にその行の背景色が真っ白になってしまいます。 あと、テキストの1列目と2列目の間に縦に境界線を引いているのですが、Using ~ End Usingを生かすと その境界線も消えてしまいます。 境界線に関しては描く順が先なので後から上から真っ白に塗ってしまっているのかなと思いますが、 マウスオーバーした行が真っ白になってしまう理由が分かりません。 Protected Overrides Sub OnDrawItem(e As DrawItemEventArgs) MyBase.OnDrawItem(e) If MyBase.DataSourceEntityList Is Nothing Then Exit Sub If MyBase.DataSourceEntityList.Count = 0 Then Exit Sub If e.Index < 0 Then Exit Sub If e.Index > (MyBase.DataSourceEntityList.Count - 1) Then Exit Sub Dim penLine As Drawing.Pen = New Drawing.Pen(Drawing.SystemColors.ControlDark) Dim borderLeft As Single = 188.0F Dim rectBounds As Drawing.Rectangle = e.Bounds Dim comboText As String = String.Empty Dim foreColor As Drawing.Color = e.ForeColor Dim checkBoxWidth As Integer = 18 '境界線 e.Graphics.DrawLine(penLine, borderLeft, e.Bounds.Top, borderLeft, e.Bounds.Bottom) ' チェックボックスの位置を考慮して左位置にプラス rectBounds.X += checkBoxWidth rectBounds.Width -= checkBoxWidth 'Using b As New Drawing.SolidBrush(BackColor) ' e.Graphics.FillRectangle(b, rectBounds) 'End Using ' 1列目描画 comboText = "テスト文字列" TextRenderer.DrawText(e.Graphics, comboText, e.Font, rectBounds, foreColor, TextFormatFlags.NoPadding) '' 2列目描画 → 一旦2列目の描画箇所をコメントアウト e.DrawFocusRectangle() End Sub
KOZ6.0

2023/01/29 23:54

DataSourceEntityList って何ですか? なんだかいろいろいじってるようなので、そこがおかしい処理をしてるのでは? 質問の件については解決してるのでクローズしてください。
ashitani

2023/01/30 06:19

"テスト文字列"の本来の表示元ソースです。 テスト時はコメントアウトしてましたが、掲載時に混在してしまいまして失礼しました。 レタリングには関係ございません。 はい、いろいろとありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問