none
ComboBoxのフォーカス表示を非表示にするか色を変更したい RRS feed

  • 質問

  • 質問させていただきます。C#にて初めてフォームアプリケーションの開発を行っております。

    コンボボックスのアイテム文字列表示に、指定した幾つかの色(Color.Redなどの固定値)を使いたいのですが、

    windows8.1のデフォルトテーマの場合、Color.Greenなどでテキストを表示すると

    コンボボックスのフォーカス色で文字がつぶれてしまい、非常に見づらくなってしまいます。

    解決策として、フォーカス/アンフォーカス時の色をこちらでコントロールできないかと思ったのですが

    それらしいドキュメントが発見できませんでした。

    ComboBox.DrawItemイベントでFillRectangle()すれば選択中の色は変わるものの、

    チェックボックスをクリックしてリスト展開したときに全て同じ色になってしまうのは解りにくくなるため避けたいです。

    何かしらの解決策はあるのでしょうか。

            private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
            {
                ComboBox cb = (ComboBox)sender;

                e.DrawBackground();
                
                // これを書くと全てがオレンジになってしまいわかりにくくなる、リストではカーソルが合っているかどうかわかるのが望ましい
                e.Graphics.FillRectangle(new SolidBrush(Color.Orange), e.Bounds);

                string text = cb.Items[e.Index].ToString();

                SizeF basestrsize = ea.Graphics.MeasureString(text, font);
                float posy = e.Bounds.Y + (e.Bounds.Height - basestrsize.Height) / 2;
                float posx = e.Bounds.X;

                // 文字色をGreenにするとWin8.1のデフォテーマでフォーカスが当たった場合文字がつぶれてしまう
                e.Graphics.DrawString(text, e.Font, new SolidBrush(Color.Green), posx, posy);

                e.DrawFocusRectangle();
            }

    2014年12月16日 15:36

回答

  • 引数のDrawItemEventArgsのStateで選択状態が判りますよ

    private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        ComboBox cb = (ComboBox)sender;
    
        e.DrawBackground();
        Color cBackground;
        Color cFont;
    
        if ((e.State & DrawItemState.Selected)== DrawItemState.Selected)
        {
            cBackground = SystemColors.Highlight;
            cFont = SystemColors.HighlightText;
            if (cb.Items[e.Index].ToString() == "1")
            {
                cBackground = Color.Red;
                cFont = Color.Blue; 
            }
        }
        else
        {
            cBackground = Color.Orange;
            cFont = Color.Green;
        }
    
        // これを書くと全てがオレンジになってしまいわかりにくくなる、リストではカーソルが合っているかどうかわかるのが望ましい
        e.Graphics.FillRectangle(new SolidBrush(cBackground ), e.Bounds);
        string text = cb.Items[e.Index].ToString();
    
        SizeF basestrsize = e.Graphics.MeasureString(text, cb.Font);
        float posy = e.Bounds.Y + (e.Bounds.Height - basestrsize.Height) / 2;
        float posx = e.Bounds.X;
    
        // 文字色をGreenにするとWin8.1のデフォテーマでフォーカスが当たった場合文字がつぶれてしまう
        e.Graphics.DrawString(text, e.Font, new SolidBrush(cFont), posx, posy);
    
        e.DrawFocusRectangle();
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク トウコツ 2014年12月17日 5:20
    2014年12月16日 23:02

すべての返信

  • 引数のDrawItemEventArgsのStateで選択状態が判りますよ

    private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        ComboBox cb = (ComboBox)sender;
    
        e.DrawBackground();
        Color cBackground;
        Color cFont;
    
        if ((e.State & DrawItemState.Selected)== DrawItemState.Selected)
        {
            cBackground = SystemColors.Highlight;
            cFont = SystemColors.HighlightText;
            if (cb.Items[e.Index].ToString() == "1")
            {
                cBackground = Color.Red;
                cFont = Color.Blue; 
            }
        }
        else
        {
            cBackground = Color.Orange;
            cFont = Color.Green;
        }
    
        // これを書くと全てがオレンジになってしまいわかりにくくなる、リストではカーソルが合っているかどうかわかるのが望ましい
        e.Graphics.FillRectangle(new SolidBrush(cBackground ), e.Bounds);
        string text = cb.Items[e.Index].ToString();
    
        SizeF basestrsize = e.Graphics.MeasureString(text, cb.Font);
        float posy = e.Bounds.Y + (e.Bounds.Height - basestrsize.Height) / 2;
        float posx = e.Bounds.X;
    
        // 文字色をGreenにするとWin8.1のデフォテーマでフォーカスが当たった場合文字がつぶれてしまう
        e.Graphics.DrawString(text, e.Font, new SolidBrush(cFont), posx, posy);
    
        e.DrawFocusRectangle();
    }


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク トウコツ 2014年12月17日 5:20
    2014年12月16日 23:02
  • 成程、DrawItemState でやりたいことは実現できました、ありがとうございました。

            private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
            {
                ComboBox cb = (ComboBox)sender;
    
                e.DrawBackground();
                Color cBackground;
    
                if (((e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit)  // コンボボックス本体の場合は明るく
                    || ((e.State & DrawItemState.Selected) == DrawItemState.Selected)       // リスト表示の選択中の場合も明るく
                )
                {
                    cBackground = Color.Gray;
                }
                else
                {
                    cBackground = Color.DimGray;
                }
    
                e.Graphics.FillRectangle(new SolidBrush(cBackground), e.Bounds);
                string text = cb.Items[e.Index].ToString();
    
                SizeF basestrsize = e.Graphics.MeasureString(text, cb.Font);
                float posy = e.Bounds.Y + (e.Bounds.Height - basestrsize.Height) / 2;
                float posx = e.Bounds.X;
    
                e.Graphics.DrawString(text, e.Font, new SolidBrush(Color.White), posx, posy);
    
                e.DrawFocusRectangle();
            }


    2014年12月17日 5:20