【问题标题】:How to Force use of Custom UITypeEditor for System Types如何强制对系统类型使用自定义 UITypeEditor
【发布时间】:2011-05-03 07:02:39
【问题描述】:

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

注意它的属性 TheColour颜色没有。

当我打开 propertyGrid 时,我可以看到 GetEditStyle 是通过这两种方法调用的,但是当涉及到 EditValue 时,它只有在您在 propertygrid 中选择 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

【问题讨论】:

  • 找到了 - 请参阅我的答案的编辑。

标签: .net propertygrid


【解决方案1】:

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

我需要实现一个 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

【讨论】:

  • 如果你从ColorConverter而不是TypeConverter继承,你会得到一个更完整的实现。
【解决方案2】:

问题是它注意到关联的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)));

【讨论】:

  • 呵呵我得到了解决方案,而您一定已经发布了您的更新,我只有在发布附录后才看到它更新。遗憾的是,没有办法让网格绘制整个单元格而不仅仅是小预览框。
  • 感谢使用 TypeDescriptor.AddAttributes 的提示,对我来说是新手。
  • 你能告诉我你是怎么发现有一个 TypeConverter 关联的吗?我正在尝试为 Dictionary&lt;string,string&gt; 执行此操作,并且很想知道如何浏览加载的转换器以及为 linqpad 中的类型注册了哪些编辑器。
  • @Maslow 您可以从针对类型查找 EditorAttribute 和 TypeConverterAttribute 开始,但由于列表可以在运行时更改,因此并不详尽
  • 我想这并不详尽,但向我展示了我想知道的TypeDescriptor.GetConverter(new Dictionary&lt;string,string&gt;()).Dump();
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多