none
[C#]PropertyGrid内にあるReadOnly項目の文字色を変更するにはどうしたら良いでしょうか? RRS feed

  • 質問

  • 度々お世話になっております。

    現在、C#上でPropertyGridを用いて各項目の表示をしております。

    そこで、色々な部分のデザイン変更を行っているのですが、

    ReadOnly項目の文字色だけどうにも変更できていない状態です。(グレー表示になるようです)

    class TestData{

            [ReadOnly(false)]
            public int NonChangeParam
            {
                get { return iNonChangeParam; }
                set { iNonChangeParam = value; }
            }

    }

           PropertyGrid clsTestGrid = new PropertyGrid();
           clsTestGrid.SelectedObject = new TestData();
           Form1.Controls.Add(clsTestGrid);

    概ねこういった形のサンプルコードです。

    この場合、NonChangeParamという項目名がグレー表示になります。

    TextBoxの場合、BackColorを指定してからForeColor…という形でReadOnlyの色が変更できるのですが、

    PropertyGridの場合はどのようにすれば良いのでしょうか。ご存知の方は教えて頂けますと幸いです。

    以上になります。

    よろしくお願い致します。

    2012年6月27日 2:32

すべての返信

  • ReadOnlyの文字色をReadOnlyじゃない文字色と同じにするのでよければ、ViewForeColorプロパティで変えられます。
    #文字以外も色変わっちゃうけど

    ViewForeColorがSystem.Drawing.SystemColors.WindowTextになっている場合のみ、ReadOnlyの項目はグレーアウトします。
    SystemColors.WindowTextにしたいときは、同じ色にせずにSystemColors.WindowTextと微妙に違う色を設定してやることでごまかせます。(RGBが1だけ違う色とかに)

    ReadOnlyの項目の文字だけを任意の色にする方法は知りません。
    #Reflectionでゴリゴリやろうとして断念した記憶が・・・


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

    2012年6月27日 8:59
  • >gekka様

    ご返信頂きありがとうございます。

    実は既にViewForeColorプロパティ自体は変更しているんですよね…。

    Color関連のプロパティは全ていじり倒した結果、ReadOnlyだけ変わりませんでしたので、困ってしまいました。

    実はReadOnlyの文字ではなく、通常の文字を表示できればOKですので、以下のようなことを試しています。

    1.ReadOnlyはReadOnlyタグで実装([ReadOnly(true)]などといった物の仮名)していますので、

      「PropertyDiscriptorを通じてうまいこと、実際にはReadOnlyな値だけれども、見た目はReadOnlyではないように見せかける」といった

      うまい回避方法が取れないか模索しています。(CanConvertFromあたりを使って。クラス形式ならこれでできます。intなどのSingleObjectは微妙なんですが)

    2.あるいは、Propertyのset部分は{}とだけ書くとReadOnlyとなりませんので、これでどうにかやるかと…。

    問題は、いずれの方法もクラス毎あるいは必ずオブジェクトを指定してReadOnlyかそうでないかが変わります。

    さすがに酷く手間ですし、デザインだけでどうにかできるならそれに越したことはないので、何か無いかと探しております。

    やっぱり難しそうですね…。うーん…。

    2012年6月27日 9:40
  • 以前同じことをしようとして断念した記憶があります。
    DevComponentsAdvanced Property Grid Controlを利用することでかなり柔軟に対応できたように思いますので、サードパーティ製のコンポーネントを利用して良いのであれば一度ご検討されてみてはいかがでしょうか。

    2012年6月27日 16:13
  • 試していませんが、GetPaintValueSupported を true にして PaintValue で独自に描画すれば対応できませんか?

    public AlwaysNormalColorEditor : UITypeEditor
    {
        public override bool GetPaintSupported(ITypeDescriptorContext ctx)
        {
            return true;
        }
        public override void PaintValue(PaintValueEventArgs e)
        {
           // : 期待した色で描画する
        }
    }
    public class TestData
    {
        [ReadOnly(true)]
        [Editor(typeof(AlwaysNormalColorEditor))]
        public int NonChangeParam
        {
            ...
        }
    }
    みたいなかんじかな? 

    2012年6月28日 1:58
  • >xin9le様

    そんなツールがあったんですか…!でも、やはり有償のようですね。

    フリーツールでもありそうな物なのですが…。

    >K.Takaoka様

    GetPaintSupportedはGetPaintValueSupportedという事で宜しいでしょうか?

    もしそうであれば、ちょっと見当違いになってしまうと思われます。

    これはSystem.Drawing.Color構造体などの、何かの画像を小さな矩形内に表示することのサポートだと思います。

    それとも、画像部分を消去して、値を自分の好きな色で表記できるのでしょうか…?

    2012年6月28日 2:42
  • 値全体の描画用なので矩形の外側にも描けますけど、大きさとかの都合で難しそうだったり前後の描画と重なってきたいした結果にならないとかあるかもしれません。

    もしかすると描画範囲がとれない・・・かな?(左上は 0,0 で描画できるはずなので、クリッピングリージョンで描画範囲が得られないかと期待するのですが)

    2012年6月28日 5:11
  • >K.Takaoka様

    試してみました。

    なるほど、PaintValue内でe.DrawStringと書くと、期待しているように文字が描けるようです。

    逆に今度は、本来の描画(元の、□valueなどといった表示がされていること)部分をうまいこと消去しないといけません。

    試しに同じ場所にてe.Clear(Color.White);としてみたところ、

    それまでの部分全体が真っ白になりました。

    おそらく、左上から順に右下まで描画を行っていたため、

    プロパティグリッド全体を真っ白にした後に、他の部分が描画されたためかと思います。

    代わりに、e.Graphics.FillRectangle(Brushes.White, e.Bounds);としてみました。

    すると、小さい画像を出す部分のみ、白で塗りつぶされました。

    指定のGridItem内のみの矩形というのは存在しないのでしょうか。

    また、白くした場合にも「本来の描画部分」は描画されていたため、この方法では無理かもしれません。

    「このEditorが指定されている場合は何も値の部分を書かないようにする」設定ができれば良いのですが…。

    2012年6月28日 7:20