propertygrid 中的 TypeConverter 仅从字符串转换,而不是

发布于 2024-08-18 09:50:20 字数 1216 浏览 3 评论 0原文

访问 propertygrid 时,仅调用 ConvertTo 方法(多次)。这会正确返回“Foo!”属性网格中的字符串。当我单击编辑时,出现异常 Cannot conversion 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;
    }
}

Only the ConvertTo method gets called(a lot of times) when accessing the propertygrid. This correctly returns the "Foo!" string in the propertygrid. When I click to edit I get an exception Cannot convert object of type Foo to type System.String.(not exactly, translated). The ConvertFrom method doesn't get called, any clues why? And the error indicates it's trying to convert TO a string, not from.

I would think when I want to edit this object, it has to convert from Foo to string, and when finished editing back.

StringConverter class:

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

Property being accessed:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

手心的温暖 2024-08-25 09:50:20

重新更新您的信息;这是一个应该作为填充程序工作的 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 { /* ... */ }

Re your update; here's a FooEditor that should work as a shim:

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

You'll obviously need to associate it:

[TypeConverter(typeof(FooTypeConverter))]
[Editor(typeof(FooEditor), typeof(UITypeEditor))]
class Foo { /* ... */ }
爱本泡沫多脆弱 2024-08-25 09:50:20

无法复制;对我来说效果很好;您应该测试 destinationTypevalue 类型,顺便说一句 - 但这并不能阻止它调用 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);
        }
    }
}

Cannot reproduce; it works fine for me; you should be testing the destinationType and type of value, btw - but that isn't stopping it calling ConvertFrom. Do you have a complete example (perhaps based on the following) that shows it not calling 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);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文