2010-01-22 85 views
5

只有ConvertTo方法在访问propertygrid时被调用(很多次)。这正确地返回“Foo!” propertygrid中的字符串。当我点击编辑时,我得到一个异常Cannot convert object of type Foo to type System.String.(不完全翻译)。 ConvertFrom方法不会被调用,为什么会有线索?并且错误表明它试图将TO转换为一个字符串,而不是从。propertygrid中的TypeConverter只能从字符串转换,而不能转换成

我想当我想编辑这个对象时,它必须从Foo转换为字符串,并且在完成编辑时返回。

类字符串转换:

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

我发现它有事情做与MultilineStringEditor,如果我禁用,它正常工作。 – 2010-01-22 12:41:51

+0

我只看到你的更新;你将不得不编写你自己的编辑器 - “MultilineStringEditor”不会**知道如何处理'Foo',所以要么说“不”,要么就是引发和处理异常。 – 2010-01-22 12:50:10

回答

5

重新更新;这里有一个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

这似乎这样做,谢谢!我想我可以使用UITypeEditor和TypeConverter。 – 2010-01-22 15:07:01

+0

@Robert - 你仍然可以;-p不要忘记一些其他控件('DataGridView'等)将只使用转换器,而不是编辑器。 – 2010-01-22 16:25:17

0

无法重现;这对我来说可以;你应该测试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); 
     } 
    } 
}