TypeConverter в таблице свойств конвертирует только из строки, а не в - PullRequest
5 голосов
/ 22 января 2010

При обращении к таблице свойств вызывается только метод ConvertTo (много раз). Это правильно возвращает "Foo!" строка в сетке свойств. Когда я нажимаю для редактирования, я получаю исключение Cannot convert object of type Foo to type System.String. (не совсем переведено). Метод ConvertFrom не вызывается, какие-либо подсказки, почему? И ошибка указывает, что он пытается преобразовать в строку, а не из.

Я бы подумал, что когда я захочу отредактировать этот объект, он должен преобразовать Foo в строку, а когда закончит редактирование обратно.

Класс StringConverter:

public class FooTypeConverter : StringConverter {
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
        return new Foo((string) value);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
        return "Foo!";
    }

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
        return true;
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
        return true;
    }
}

Доступность объекта:

Foo _foo = new Foo();
[Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(UITypeEditor))]
[TypeConverter(typeof(FooTypeConverter))]
public Foo Foo {
    get {
        return _foo;
    }
    set {
        _foo = value;
    }
}

Ответы [ 2 ]

5 голосов
/ 22 января 2010

Re ваше обновление; Вот FooEditor, который должен работать как прокладка:

class FooEditor : UITypeEditor
{
    MultilineStringEditor ed = new MultilineStringEditor();
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        Foo foo = value as Foo;
        if (foo != null)
        {
            value = new Foo((string)ed.EditValue(provider, foo.Value));
        }
        return value;        
    }
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return ed.GetEditStyle();
    }
    public override bool  IsDropDownResizable {
        get { return ed.IsDropDownResizable; }
    }
}

Вам, очевидно, нужно будет связать это:

[TypeConverter(typeof(FooTypeConverter))]
[Editor(typeof(FooEditor), typeof(UITypeEditor))]
class Foo { /* ... */ }
0 голосов
/ 22 января 2010

Невозможно воспроизвести; Он отлично работает для меня; вы должны тестировать destinationType и тип value, кстати - но это не останавливает его, вызывая ConvertFrom. У вас есть полный пример (возможно, основанный на следующем), который показывает, что не вызывает ConvertFrom?

using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Forms;
public class FooTypeConverter : StringConverter {
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        return new Foo("FooTypeConverter.ConvertFrom: " + Convert.ToString(value));
    }
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        return "FooTypeConverter.ConvertTo: " + ((Foo)value).Value;
    }
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return true;
    }
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return true;
    }
}
[TypeConverter(typeof(FooTypeConverter))]
class Foo
{
    public string Value { get; set; }
    public Foo(string value) { Value = value; }

    public override string ToString()
    {
        return "Foo.ToString";
    }
}
class Test
{
    public Foo Foo { get; set; }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        using(Form form = new Form())
        using (PropertyGrid grid = new PropertyGrid())
        {
            grid.Dock = DockStyle.Fill;
            grid.SelectedObject = new Test { Foo = new Foo("Main") };
            form.Controls.Add(grid);
            Application.Run(form);
        }
    }
}
...