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

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

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.100547 の関連記事表示

<< 0 >>
■100547  コンボボックスの文字色を変更する方法
□投稿者/ wani -(2022/09/10(Sat) 10:44:51)

    分類:[.NET 全般] 



    VB.NETを使用しております。



    コンボボックスの文字色を変更したいと考えているのですが

    http://dobon.net/vb/dotnet/control/cbownerdraw.html

    このページの方法で変更することができました。


    しかし、外観(FlatStyle)がStandardではなくFlatに変わってしまいます。

    Standardの状態で文字色だけを変更するにはどのようにしたら良いですか?

親記事 /過去ログ175より / 関連記事表示
削除チェック/

■100548  Re[1]: コンボボックスの文字色を変更する方法
□投稿者/ WebSurfer -(2022/09/10(Sat) 11:05:05)
    No100547 (wani さん) に返信

    何を何で作っているか書けませんか?

    (例: Windows Forms アプリを Visual Studio 2022 を使ってフレームワークを
    .NET Framework 4.8 で作っています)
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100549  Re[2]: コンボボックスの文字色を変更する方法
□投稿者/ wani -(2022/09/10(Sat) 11:46:48)
    Windows Forms アプリを Visual Studio 2015 を使ってフレームワークを
    .NET Framework 4.5 で作っています
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100551  Re[1]: コンボボックスの文字色を変更する方法
□投稿者/ KOZ -(2022/09/10(Sat) 22:56:02)
    No100547 (wani さん) に返信
    > http://dobon.net/vb/dotnet/control/cbownerdraw.html
    > このページの方法で変更することができました。
    > しかし、外観(FlatStyle)がStandardではなくFlatに変わってしまいます。

    Flat ではなく、DropDownList が DropDown と同じような表示になるのではないですか?

    > Standardの状態で文字色だけを変更するにはどのようにしたら良いですか?

    ComboBox 自身を VisualStyleElement を使って VisualStyleRenderer で背景を描画します。

    ComboBox の DropDownButton 部分については、VisualStyleElement に定義があるのですが、他は無いので
    https://docs.microsoft.com/en-us/windows/win32/controls/parts-and-states
    を参照して、定義します。

    描画時には

    VisualStyleRenderer.IsBackgroundPartiallyTransparent メソッドで現在の visual スタイル要素の
    背景の一部が半透明である (アルファ ブレンドされている) かどうかをチェックし、True なら
    VisualStyleRenderer.DrawParentBackground で親の背景を描画します。

    VisualStyleRenderer.SetParameters で VisualStyleElement を反映します。

    VisualStyleRenderer.DrawBackground で描画します。

    という感じになります。

    フォーカスを得た状態、マウスがホバーした状態などのステータスにあわせてこれらを描画しなくてはならないので、
    はっきりいってメチャメチャ面倒です。
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100552  Re[2]: コンボボックスの文字色を変更する方法
□投稿者/ wani -(2022/09/11(Sun) 15:19:15)
    No100551 (KOZ さん) に返信

    ありがとうございます。

    レベルが高すぎて私にはどのように作成したら良いか分かりません。

    どうやれば良いかコードをご提示いただけないでしょうか?
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100554  Re[3]: コンボボックスの文字色を変更する方法
□投稿者/ KOZ -(2022/09/12(Mon) 02:21:56)
    2022/09/12(Mon) 07:27:48 編集(投稿者)

    No100552 (wani さん) に返信

    わたしの疑問には答えてもらえないんでしょうか?

    > レベルが高すぎて私にはどのように作成したら良いか分かりません。
    > どうやれば良いかコードをご提示いただけないでしょうか?

    CP_BACKGROUND な VisualStyleElement は、作成はできるものの、SetPrameters でセットするとエラーになります。
    API を使って直書きしてみたのですが、どうやら、DropDown スタイルのテーマのようです。

    DropDownList スタイルの場合、背景はボタンを描画するのが正解のようです。

    とりあえず、マウスがホバーしホットな状態の ComboBox を作ってみました。

    あとは面倒なのでおまかせします。
    状態を検出して VisualStyles.PushButtonState.Hot/CBXSR_HOT の部分を切り替えてください。
    テキストの描画位置も要調整。

    フォーカスを得たときの点線は、ControlPaint.DrawFocusRectangle メソッドを使って描画できます。
    https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.controlpaint.drawfocusrectangle?view=netframework-4.5

    Public Class ComboBoxEx
    Inherits ComboBox

    <ThreadStatic>
    Private Shared vsRenderer As VisualStyles.VisualStyleRenderer
    Private Shared dropdownButtonElement As VisualStyles.VisualStyleElement =
    VisualStyles.VisualStyleElement.CreateElement("COMBOBOX", CP_DROPDOWNBUTTONRIGHT, CBXSR_NORMAL)

    Private Const CP_BACKGROUND As Integer = 2
    Private Const CP_TRANSPARENTBACKGROUND As Integer = 3
    Private Const CP_BORDER As Integer = 4
    Private Const CP_READONLY As Integer = 5
    Private Const CP_DROPDOWNBUTTONRIGHT As Integer = 6
    Private Const CP_DROPDOWNBUTTONLEFT As Integer = 7
    Private Const CP_CUEBANNER As Integer = 8

    Private Const CBXSR_NORMAL As Integer = 1
    Private Const CBXSR_HOT As Integer = 2
    Private Const CBXSR_PRESSED As Integer = 3
    Private Const CBXSR_DISABLED As Integer = 4

    Protected Overrides Sub CreateHandle()
    MyBase.CreateHandle()
    Dim bUserPaint As Boolean = Application.RenderWithVisualStyles AndAlso
    DropDownStyle = ComboBoxStyle.DropDownList AndAlso
    FlatStyle = FlatStyle.Standard
    SetStyle(ControlStyles.UserPaint Or
    ControlStyles.AllPaintingInWmPaint Or
    ControlStyles.OptimizedDoubleBuffer, bUserPaint)
    End Sub

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
    If vsRenderer Is Nothing Then
    vsRenderer = New VisualStyles.VisualStyleRenderer(dropdownButtonElement)
    End If
    If vsRenderer.IsBackgroundPartiallyTransparent() Then
    vsRenderer.DrawParentBackground(e.Graphics, ClientRectangle, Me)
    End If

    Dim cr As Rectangle = ClientRectangle
    Dim face As New Rectangle(-1, -1, cr.Width + 2, cr.Height + 2)
    Dim buttonWidth As Integer = SystemInformation.HorizontalScrollBarArrowWidth
    Dim buttonRect As New Rectangle(cr.Right - buttonWidth - 1, cr.Top, buttonWidth, cr.Height)
    Dim buttonFace As New Rectangle(buttonRect.X + 1, 0, buttonRect.Width - 2, buttonRect.Height - 2)

    ButtonRenderer.DrawButton(e.Graphics, face, VisualStyles.PushButtonState.Hot)
    vsRenderer.SetParameters(dropdownButtonElement.ClassName,
    dropdownButtonElement.Part,
    CBXSR_HOT)
    vsRenderer.DrawBackground(e.Graphics, buttonRect, buttonFace)
    TextRenderer.DrawText(e.Graphics, Text, Font, cr, ForeColor,
    TextFormatFlags.Left Or TextFormatFlags.VerticalCenter)
    End Sub

    End Class

    使い方

    Public Class Form1

    Public Sub New()
    InitializeComponent()

    Dim cbo As New ComboBoxEx
    cbo.Size = New Size(100, 20)
    cbo.Items.AddRange(New Object() {"AAA", "BBB", "CCC"})
    cbo.ForeColor = Color.Red
    cbo.DropDownStyle = ComboBoxStyle.DropDownList
    Controls.Add(cbo)
    End Sub

    End Class

    とまぁ、ここまで書いたんですが、たいていは面倒なのでやめます。とか無応答になっちゃうんですよね(^_^;)
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100553  Re[1]: コンボボックスの文字色を変更する方法
□投稿者/ 魔界の仮面弁士 -(2022/09/11(Sun) 19:20:34)
    No100547 (wani さん) に返信
    > コンボボックスの文字色を変更したいと考えているのですが
    > http://dobon.net/vb/dotnet/control/cbownerdraw.html
    > このページの方法で変更することができました。

    DrawItem イベントにおいて、e.BackColor や e.ForeColor に頼らずに独自の色にする場合は、
    その時点の e.State の値を検査する必要がありますね。


    No100547 (wani さん) に返信
    > しかし、外観(FlatStyle)がStandardではなくFlatに変わってしまいます。

    FlatStyle を意図的に Standard に変更したとしても、Flat の見た目になるということでしょうか?
    手元の環境では確認できませんでした。
    ・Win11 21H2 + .NET Framework 4.8.1
    ・Win11 21H2 + .NET Framework 3.5

    FlatStyle の Standard / Flat / Popup の見た目というのは、
    .NET / .NET Framework のバージョンや、
    実行 OS や VisualStyles テーマによっても異なってくるかと思いますが、
    今回の環境はどういう組み合わせでしたか?
    https://github.com/dotnet/winforms/issues/7727
    https://www.cnblogs.com/leiyongbo/p/12193639.html


    No100552 (wani さん) に返信
    > ■No100551 (KOZ さん) に返信
    > > フォーカスを得た状態、マウスがホバーした状態などのステータスにあわせてこれらを描画しなくてはならないので、
    > どうやれば良いかコードをご提示いただけないでしょうか?

    たとえばボタン部のホバーに関しては、その時点のマウス位置に応じて描画内容を変化させます。

    下記は Flat な ComboBox を作る場合の例なので、そのものずばりでは無いですが、
    マウス位置の判定処理を作りこむ際の参考にはなるかと思います。
    https://www.codeproject.com/Articles/11338/Flat-ComboBox-with-MS-Office-XP-2003-style-support?

    GDI+ リソースの Dispose 処理が漏れていたり、Option Strict Off 前提のソースだったりと、
    そのまま丸写しするには、少々難があるソースですが…。


    > レベルが高すぎて私にはどのように作成したら良いか分かりません。
    手も足も出ないようなら手間がかかりすぎるので、諦めた方が無難でしょう。
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100555  Re[2]: コンボボックスの文字色を変更する方法
□投稿者/ wani -(2022/09/12(Mon) 22:02:13)
    >>■No100551 (KOZ さん) に返信

    ありがとうございます。

    素晴らしいです。

    いいところまでは来ています。

    後は、

    1.ホイールした時にアイテムを変更する
    2.アイテム毎に、文字色を変更する
    3.マウスがコンボボックス上にない場合には外観を通常のものにする

    の三種だと思います。

    3.はMouseEnterとMouseLeaveを使えば良いのでしょうか?
    1.や2.はどのメソッドを使えば良いでしょうか?
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100556  Re[3]: コンボボックスの文字色を変更する方法
□投稿者/ KOZ -(2022/09/12(Mon) 23:00:17)
    2022/09/12(Mon) 23:34:09 編集(投稿者)

    No100555 (wani さん) に返信
    > 1.ホイールした時にアイテムを変更する

    OnMouseWheel メソッドを使って変更してください。
    e.Delta で上下を判定します。

    > 2.アイテム毎に、文字色を変更する

    TextRenderer.DrawText の ForeColor を変更してください。
    リスト部分は、DOBON さんのコードを流用すれば良いですね。

    > 3.マウスがコンボボックス上にない場合には外観を通常のものにする

    .NET のソースコードをあさっているときに目にしたロジックを紹介します。

    Private _MouseIsOver As Boolean = False
    Private _MouseIsDown As Boolean = False

    Protected Property MouseIsOver As Boolean
    Get
    Return _MouseIsOver
    End Get
    Set(value As Boolean)
    If _MouseIsOver <> value Then
    _MouseIsOver = value
    Invalidate()
    End If
    End Set
    End Property

    Protected Property MouseIsDown As Boolean
    Get
    Return _MouseIsDown
    End Get
    Set(value As Boolean)
    If _MouseIsDown <> value Then
    _MouseIsDown = value
    Invalidate()
    End If
    End Set
    End Property

    Protected Overrides Sub OnMouseCaptureChanged(e As EventArgs)
    MyBase.OnMouseCaptureChanged(e)
    MouseIsOver = False
    MouseIsDown = False
    End Sub

    Protected Overrides Sub OnMouseLeave(e As EventArgs)
    MyBase.OnMouseLeave(e)
    MouseIsOver = False
    End Sub

    Protected Overrides Sub OnMouseHover(e As EventArgs)
    MyBase.OnMouseHover(e)
    MouseIsOver = True
    End Sub

    Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
    MyBase.OnMouseDown(e)
    MouseIsDown = True
    End Sub

    Protected Overrides Sub OnMouseUp(e As MouseEventArgs)
    MyBase.OnMouseUp(e)
    MouseIsDown = False
    End Sub

    OnPaint で MouseIsOver/MouseIsDown プロパティ、標準の Enabled/DroppedDown プロパティを参照して判定できます。
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100557  Re[4]: コンボボックスの文字色を変更する方法
□投稿者/ wani -(2022/09/13(Tue) 11:43:49)
    ありがとうございます。
    
    
            If MouseIsOver = True Then
    
                ButtonRenderer.DrawButton(e.Graphics, face, VisualStyles.PushButtonState.Hot)
    
            ElseIf MouseIsDown = True Then
    
                ButtonRenderer.DrawButton(e.Graphics, face, VisualStyles.PushButtonState.Pressed)
    
            Else
    
                ButtonRenderer.DrawButton(e.Graphics, face, VisualStyles.PushButtonState.Normal)
    
            End If
    
    
    こんな感じでしょうか?
    
    何となくはできているのですが、
    普通のコンボボックスだとマウスホバーしてすぐに外観が変化するのですが、
    このカスタムクラスだとなぜか1秒くらい遅延してから外観が変化します。
    なぜでしょうか?
    
    また、コンボボックスの右端にある三角形みたいなマークの上は
    マウスをホバーしていなくとも常にHotの状態なのですが
    どこかで設定する必要がありますでしょうか?
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100558  Re[5]: コンボボックスの文字色を変更する方法
□投稿者/ KOZ -(2022/09/13(Tue) 15:03:12)
    No100557 (wani さん) に返信
    > こんな感じでしょうか?

    操作して違和感がないのであればいいんじゃないでしょうか。

    > 普通のコンボボックスだとマウスホバーしてすぐに外観が変化するのですが、
    > このカスタムクラスだとなぜか1秒くらい遅延してから外観が変化します。

    ちょっと違います。
    普通のコンボボックスではマウスがコントロールに侵入すると徐々に明るくなっていきますが、
    このクラスでは、しばらくしてからスパッと外観が変わります。
    その動きを再現するのであれば、ご自分で研究なさってください。

    > また、コンボボックスの右端にある三角形みたいなマークの上は
    > マウスをホバーしていなくとも常にHotの状態なのですが
    > どこかで設定する必要がありますでしょうか?

    vsRenderer.SetParameters の3つめの引数(CBXSR_HOT)の部分を変更してください。
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100559  Re[6]: コンボボックスの文字色を変更する方法
□投稿者/ KOZ -(2022/09/13(Tue) 16:30:02)
    No100558 (KOZ) に返信
    > ちょっと違います。
    > 普通のコンボボックスではマウスがコントロールに侵入すると徐々に明るくなっていきますが、
    > このクラスでは、しばらくしてからスパッと外観が変わります。
    > その動きを再現するのであれば、ご自分で研究なさってください。

    BeginBufferedAnimation 等の API を使うようです。
    .NET には部品が用意されていないようなので、頑張って再現してみてください。

    https://www.pg-fl.jp/program/tips/ownanim.htm
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100562  Re[7]: コンボボックスの文字色を変更する方法
□投稿者/ KOZ -(2022/09/18(Sun) 11:25:37)
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100563  Re[8]: コンボボックスの文字色を変更する方法
□投稿者/ wani -(2022/09/18(Sun) 23:17:37)
    No100562 (KOZ さん) に返信

    ありがとうございます。

    ホイールは動作するようになったことを確認できました。

    しかし、なぜか私の環境ではマウスをホバーした時に
    外観が変わるのはBeginBufferedAnimationを使わなかった時と同じく
    タイムラグが発生します。

    もしかして、どこかの設定を変更する必要がありますか?

    関係ないかも知れませんが、
    .NET Framework4.5.2に変更して使用しています。


    あと、項目毎に色を変更する方法もご提示いただけると助かります。
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100564  Re[9]: コンボボックスの文字色を変更する方法
□投稿者/ KOZ -(2022/09/19(Mon) 04:11:59)
    2022/09/19(Mon) 04:25:26 編集(投稿者)

    No100563 (wani さん) に返信
    > ホイールは動作するようになったことを確認できました。

    ホイールに対応するようなコードは書いてません。

    > しかし、なぜか私の環境ではマウスをホバーした時に
    > 外観が変わるのはBeginBufferedAnimationを使わなかった時と同じく
    > タイムラグが発生します。
    > もしかして、どこかの設定を変更する必要がありますか?

    よくわかりません。
    もしかして github のコードの一部をコピペして利用しているんでしょうか?

    > あと、項目毎に色を変更する方法もご提示いただけると助かります。

    DrawItem イベントで何かやっているんだと思いますが、
    OnDrawItem をオーバーライドし、その処理を書いてください。

記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100565  Re[10]: コンボボックスの文字色を変更する方法
□投稿者/ wani -(2022/09/19(Mon) 10:41:43)
    No100564 (KOZ さん) に返信

    > よくわかりません。
    もしかして github のコードの一部をコピペして利用しているんでしょうか?

    いえ、コードを丸ごとダウンロードして使用しております。


    > OnDrawItem をオーバーライドし、その処理を書いてください。

    私には難しいため、お手本を見せていただけないでしょうか?
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100566  Re[11]: コンボボックスの文字色を変更する方法
□投稿者/ KOZ -(2022/09/19(Mon) 13:28:40)
    No100565 (wani さん) に返信

    ホイールの話はどうなったんでしょう?

    > いえ、コードを丸ごとダウンロードして使用しております。

    ちょっと見当がつきません。
    Form1.vb に通常の ComboBox と ComboBoxEx が張り付けてありますが、
    比較して動きが遅いということでしょうか。

    >>OnDrawItem をオーバーライドし、その処理を書いてください。
    > 私には難しいため、お手本を見せていただけないでしょうか?

    http://dobon.net/vb/dotnet/control/cbownerdraw.html
    を参考に実現したのではないですか?
    どのようなコードを書いたのでしょうか?
    ほぼそのまま使えるはずなのですが。

記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/

■100575  Re[12]: コンボボックスの文字色を変更する方法
□投稿者/ radian -(2022/09/21(Wed) 10:33:13)
    2022/09/21(Wed) 10:57:05 編集(投稿者)

    > ■No100565 (wani さん) に返信
    >>私には難しいため、お手本を見せていただけないでしょうか?

    (意訳)
    コントロール描画の基本全然理解してないけど、サンプルコード読むのも勉強するのも面倒だから
    お前がコード代わりに全部書いてくれ

    自力描画の処理を他人に書いて貰った所で、基本理解してないと
    その後の保守出来ないと思うけど大丈夫?
    参考にしたWebサイトや、書いて貰ったサンプルコード弄りながら
    実際に試行錯誤してみて、試してみた結果何がおかしいか、
    何が判らなくて先に進めないかを書きましょう。
    難しい、だけで何も試していないなら、質問ではなく只の作業の丸投げです。
記事No.100547 のレス /過去ログ175より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -