如何强制使用自定义UITypeEditor进行系统类型

时间:2010-11-01 06:26:38

标签: .net propertygrid

我有一个自定义UITypeEditor,它使用我的程序使用propertygrid进行颜色选择,但是如果我只暴露system.drawing.color,我似乎无法激活它。我需要在调用我的UITypeEditor之前用CustomType包装Color。

请注意属性 TheColour 颜色没有。

当我打开propertyGrid时,我可以看到通过这两种方法调用GetEditStyle,但是当涉及到EditValue时,只有在属性网格中选择TheColour时才会调用它。选择“颜色属性”

时,将显示“正常颜色”下拉列表

我错过了什么?

<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

2 个答案:

答案 0 :(得分:6)

问题是它注意到关联的TypeConverter支持枚举值。我们需要禁用它;请注意,我们也可以从默认实现继承来获取颜色预览绘画(C#中的示例,但应该易于翻译):

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;}
}

如果您希望将其应用于所有 Color属性,还有一种方法可以做到这一点,这样您就不需要装饰每个属性;在应用程序的初始化代码中的某处,执行:

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

答案 1 :(得分:0)

我想我找到了解决这个问题的方法。

我需要实现一个TypeConverter来强制GetStandardValuesSupported返回false。

然后我可以取消使用TheColour属性并使用。

<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

它有点难看,因为颜色在框中表示为所选颜色,但文本打印在PropertyGridCell的其余部分,所以我还向Converter添加了一些覆盖,只返回空字符串。 (我更倾向于将整个单元格绘制成颜色,而不仅仅是小框。)

转换器类。

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