2

I want to draw the Property value in my PropertyGrid in a similar fashion as owner-drawing items in a ListView (Details), and other controls.

If a Property is declared of type Color, its value is drawn with a swatch of the color next to a string description. If a Property is a type of Image, a thumbnail of the image is drawn next to a string description.

I have a property that is a class that contains three Properties of type Color. I want to draw all three colors in the PropertyGrid next to the Property name. The class has an ExpandableObjectConverter as the TypeConverter, where the colors are edited, but the only option I know of for changing how the Property's value is displayed is to use a TypeConverter to return a String.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
RJPisscat
  • 53
  • 4
  • You need to create a editor for your type (which has 3 color properties) by deriving from [UITypeEditor](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.design.uitypeeditor?view=net-5.0&WT.mc_id=DT-MVP-5003235) and overriding its [GetPaintValueSupported](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.design.uitypeeditor.getpaintvaluesupported?view=net-5.0&WT.mc_id=DT-MVP-5003235) and [PaintValue](https://learn.microsoft.com/en-us/dotnet/api/system.drawing.design.uitypeeditor.paintvalue?view=net-5.0&WT.mc_id=DT-MVP-5003235). – Reza Aghaei Jan 21 '21 at 04:36

1 Answers1

3

You need to create a editor for your type (which has 3 color properties) by deriving from UITypeEditor and overriding its GetPaintValueSupported and PaintValue. Than register the editor for your class using an Editor attribute:

enter image description here

Exapmle

using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
public class MyComponent : Component
{
    public SampleClass SampleProperty { get; set; } = new SampleClass();
}
[TypeConverter(typeof(ExpandableObjectConverter))]
[Editor(typeof(SampleClassEditor), typeof(UITypeEditor))]
public class SampleClass
{
    public Color Color1 { get; set; } = Color.Red;
    public Color Color2 { get; set; } = Color.Green;
    public Color Color3 { get; set; } = Color.Blue;
}
public class SampleClassEditor : UITypeEditor
{
    public override bool GetPaintValueSupported(ITypeDescriptorContext context)
    {
        return true;
    }
    public override void PaintValue(PaintValueEventArgs e)
    {
        var sample = e.Value as SampleClass;
        if (sample != null)
        {
            int x = e.Bounds.X, y = e.Bounds.Y;
            int w = e.Bounds.Width, h = e.Bounds.Height;
            using (var b = new SolidBrush(sample.Color1))
                e.Graphics.FillRectangle(b, x, y, w / 3, h);
            using (var b = new SolidBrush(sample.Color2))
                e.Graphics.FillRectangle(b, x += w / 3, y, w / 3, h);
            using (var b = new SolidBrush(sample.Color3))
                e.Graphics.FillRectangle(b, x += w / 3, y, w / 3 + 1, h);
        }
        base.PaintValue(e);
    }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • *smacking head* I looked in every wrong place for events or base classes with Paint support. I use UITypeEditor frequently and I couldn't see "Paint" in the overridable methods. How embarrassing. THANK YOU! Your sample is excellent, it will certainly help others as well. – RJPisscat Jan 21 '21 at 15:30
  • No problem, well it's not that obvious, until you learn it :) – Reza Aghaei Jan 22 '21 at 09:51
  • By the way, you may want to take a [tour] :) – Reza Aghaei Jan 23 '21 at 14:45