Как принудительно использовать Custom UITypeEditor для системных типов

У меня есть собственный UITypeEditor, который используется для выбора цвета в моей программе с помощью сетки свойств, но я не могу заставить его активироваться, если просто выставлю system.drawing.color. Мне нужно обернуть Color с помощью CustomType, прежде чем он вызовет мой UITypeEditor.

Обратите внимание на свойство TheColour, оно работает. Цвет — нет.

Когда я открываю propertyGrid, я вижу, что GetEditStyle вызывается обоими методами, но когда дело доходит до EditValue, он вызывается только тогда, когда вы выбираете TheColour в 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

person Paul Farry    schedule 01.11.2010    source источник
comment
Нашел - см. редактирование моего ответа.   -  person Marc Gravell    schedule 01.11.2010


Ответы (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)));
person Marc Gravell    schedule 01.11.2010
comment
хе-хе, я получил решение, хотя вы, должно быть, опубликовали свое обновление, я увидел его обновление только после того, как опубликовал свое дополнение. жаль, что нет способа попросить сетку закрасить всю ячейку, а не только маленькое окно предварительного просмотра. - person Paul Farry; 01.11.2010
comment
Спасибо за совет по использованию TypeDescriptor.AddAttributes, нового для меня. - person wangzq; 17.11.2010
comment
Можете ли вы рассказать мне, как вы обнаружили, что TypeConverter был связан? Я пытаюсь сделать это для Dictionary<string,string> и хотел бы знать, как просматривать загруженные конвертеры и какие редакторы зарегистрированы для типа, например, в linqpad. - person Maslow; 26.05.2011
comment
@Maslow, вы можете начать с поиска EditorAttribute и TypeConverterAttribute по типу, но, поскольку список может меняться во время выполнения, он не является исчерпывающим. - person Marc Gravell; 26.05.2011
comment
Я полагаю, что это не исчерпывающая информация, но она показала мне то, что я хотел знать TypeDescriptor.GetConverter(new Dictionary<string,string>()).Dump(); - person Maslow; 26.05.2011
comment
может быть, вы можете взглянуть на это? stackoverflow.com/questions/6141010/ - person Maslow; 26.05.2011

Думаю, я нашел решение этой проблемы.

Мне нужно было реализовать 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, поэтому я также добавил некоторые переопределения в конвертер, чтобы просто возвращать пустые строки. (Я бы предпочел закрасить всю ячейку цветом, а не только маленькую коробку).

Преобразователь класса.

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
person Paul Farry    schedule 01.11.2010
comment
Если вы наследуете от ColorConverter вместо TypeConverter, вы получите гораздо более полную реализацию. - person Marc Gravell; 01.11.2010