.net 如何强制对系统类型使用自定义UITypeEditor

.net 如何强制对系统类型使用自定义UITypeEditor,.net,propertygrid,.net,Propertygrid,我有一个自定义UITypeEditor,用于使用propertygrid的程序进行颜色选择,但如果我只显示system.drawing.color,我似乎无法激活它。在调用UITypeEditor之前,我需要使用CustomType包装颜色 请注意其工作颜色的属性。这颜色不合适 当我打开propertyGrid时,我可以看到GetEditStyle是通过这两种方法调用的,但是当涉及到EditValue时,只有在propertyGrid中选择颜色时才会调用它。选择“颜色属性”时,将显示“正常颜色”

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

请注意其工作颜色的属性。这颜色不合适

当我打开propertyGrid时,我可以看到GetEditStyle是通过这两种方法调用的,但是当涉及到EditValue时,只有在propertyGrid中选择颜色时才会调用它。选择“颜色属性”时,将显示“正常颜色”下拉列表

我错过了什么

<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

问题在于,它注意到关联的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;}
}
如果你想把它应用于所有的颜色属性,还有一种方法可以做到,这样你就不需要装饰每一个属性;在应用程序初始化代码期间的某个地方,执行:

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

我想我已经找到了解决这个问题的办法

我需要实现一个类型转换器来强制GetStandardValuesSupported返回false

然后我可以去掉颜色属性,只使用它

<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

找到它-请参阅编辑我的答案。呵呵,我得到了解决方案,而你一定已经发布了你的更新,我只是在发布我的附录后才看到它的更新。遗憾的是,没有办法让网格绘制整个单元格,而不仅仅是一个小预览框。感谢您提供了使用TypeDescriptor.AddAttributes的技巧,这对我来说是新的。您能告诉我您是如何发现与TypeConverter相关联的吗?我正在为Dictionary做这项工作,我想知道如何浏览加载的转换器以及为类型注册了哪些编辑器,例如在linqpad中。@Maslow您可以根据类型查找EditorAttribute和TypeConverterAttribute,但是由于列表可以在运行时更改,这并不是详尽的,我想这并不是详尽的,而是向我展示了我想知道的TypeDescriptor.GetConverternew Dictionary.Dump;如果您从ColorConverter而不是TypeConverter继承,您将获得更完整的实现。
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