开发者

How to Force use of Custom UITypeEditor for System Types

I have a custom UITypeEditor that is in use for Colour Selection with my program using the propertygrid, but I can't seem to get it to activate if I just expose system.drawing.color. I need to wrap the Color with a CustomType before it will invoke my UITypeEditor.

Note the Property TheColour it works. The Colour doesn't.

When I open the propertyGrid, I can see GetEditStyle is called via both methods, but when it comes to EditValue it is only called when you select TheColour in the propertygrid. The Normal Colour dropdown is shown when you select Colour Property

What am I missing?

<CategoryAttribute("Order Colour"), _
 Browsable(True), _
 DisplayName("The Colour"), _
 Description("The background colour for orders from this terminal"), _
EditorAttribute(GetType(IKMDependency.ColourSelectorEditor), _ 
GetType(System.Drawing.Design.UITypeEditor))> _
Public Property TheColour() As MyColour
    Get
        Return mMyColor
    End Get
    Set(ByVal value As MyColour)
        If value.Colour <> mMyColor.Colour Then
            mColor = value.Colour
            mMyColor = value
            mIsDirty = True
        End If
    End Set开发者_如何学运维
End Property

<CategoryAttribute("Order Colour"), _
 Browsable(True), _
 DisplayName("Colour"), _
 Description("The background colour for orders from this terminal"), _
EditorAttribute(GetType(IKMDependency.ColourSelectorEditor), _ 
GetType(System.Drawing.Design.UITypeEditor))> _
Public Property Colour() As Color
    Get
        Return mColor
    End Get
    Set(ByVal value As Color)
        If mColor <> value Then
            mColor = value
            mMyColor = New MyColour(mColor)
            mIsDirty = True
        End If
    End Set
End Property


The problem is that it is noticing that the associated TypeConverter supports enumerated values. We need to disable that; note we can also inherit from the default implementations to get things like the color preview painting (examples in C#, but should be easy to translate):

class MyColorEditor : ColorEditor {
    public override UITypeEditorEditStyle GetEditStyle(
        ITypeDescriptorContext context) {
         return UITypeEditorEditStyle.Modal;
    }
    public override object  EditValue(
       ITypeDescriptorContext context, IServiceProvider provider, object value) {
        MessageBox.Show(
              "We could show an editor here, but you meant Green, right?");
       return Color.Green;
    }
}
class MyColorConverter : ColorConverter { // reference: System.Drawing.Design.dll
    public override bool GetStandardValuesSupported(
            ITypeDescriptorContext context) {
        return false;
    }
}
class TestObject
{
    [Category("Order Colour"), Browsable(true), DisplayName("Colour")]
    [Description("The background colour for orders from this terminal")]
    [Editor(typeof(MyColorEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(MyColorConverter))]
    public Color Colour {get;set;}
}

If you want this to apply to all Color properties, there is also a way to do it such that you don't need to decorate every property; somewhere during your app's initialization code, execute:

TypeDescriptor.AddAttributes(typeof(Color),
    new EditorAttribute(typeof(MyColorEditor), typeof(UITypeEditor)),
    new TypeConverterAttribute(typeof(MyColorConverter)));


I think i've found a solution to this problem.

I needed to implement a TypeConverter to force the GetStandardValuesSupported to return false.

I can then do away with TheColour property and just use.

<CategoryAttribute("Order Colour"), _
Browsable(True), _
DisplayName("Custom Colour to Use"), _
Description("The background colour for orders from this terminal"), _
EditorAttribute(GetType(IKMDependency.ColourSelectorEditor), GetType(System.Drawing.Design.UITypeEditor)), _
TypeConverter(GetType(ColourTypeConverter))> _
Public Property Colour() As Color
    Get
        Return mColor
    End Get
    Set(ByVal value As Color)
        If mColor <> value Then
            mColor = value
            mIsDirty = True
        End If
    End Set
End Property

it's a bit ugly because the colour is represented in the box as the colour selected, but the text is printed in the rest of the PropertyGridCell so I also added some overrides to the Converter to just return empty strings. (I would have preferred to paint the entire cell the colour rather than just the little box).

The Converter class.

Public Class ColourTypeConverter
    Inherits TypeConverter

    Public Overrides Function GetStandardValuesSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
        Return False
    End Function

    Public Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
        If sourceType Is GetType(String) Then Return False
        Return MyBase.CanConvertFrom(context, sourceType)
    End Function

    Public Overrides Function ConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As System.Type) As Object
        If destinationType Is GetType(String) Then Return String.Empty
        Return MyBase.ConvertTo(context, culture, value, destinationType)
    End Function

    Public Overrides Function ConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object
        Return MyBase.ConvertFrom(context, culture, value)
    End Function

    Public Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean
        If destinationType Is GetType(String) Then Return False
        Return MyBase.CanConvertTo(context, destinationType)
    End Function
End Class
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜