2010-01-22 12 views
5

Solo el método ConvertTo se llama (muchas veces) al acceder a propertygrid. Esto devuelve correctamente el "¡Foo!" cadena en la propiedad grid Cuando hago clic para editar recibo una excepción Cannot convert object of type Foo to type System.String. (no exactamente, traducida). El método ConvertFrom no se llama, ¿por qué? Y el error indica que está tratando de convertir A una cadena, no de.TypeConverter en propertygrid solo se convierte de cadena, no en

Creo que cuando quiero editar este objeto, tiene que convertir de Foo a cadena, y cuando termina de editar de nuevo. clase

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

propiedad está accediendo a:

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

descubrí que tiene algo que ver con la MultilineStringEditor, si inhabilito eso, funciona correctamente –

+0

Acabo de ver su actualización; tendrá que escribir su propio editor: 'MultilineStringEditor' no ** va a saber cómo procesar un' Foo', por lo tanto, está diciendo "no", o se está produciendo y manejando una excepción. –

Respuesta

5

Re su actualización; aquí hay un FooEditor que debería funcionar como una cuña:

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

Obviamente va a necesita asociarlo:

[TypeConverter(typeof(FooTypeConverter))] 
[Editor(typeof(FooEditor), typeof(UITypeEditor))] 
class Foo { /* ... */ } 
+0

Eso parece hacerlo, ¡gracias! Estaba pensando que podría usar TANTO un UITypeEditor como un TypeConverter. –

+0

@Robert: aún puede ;-p No olvide que algunos otros controles ('DataGridView', etc.) solo usarán el convertidor, no el editor. –

0

no puede reproducir; Funciona bien para mí; debería probar el destinationType y el tipo de value, por cierto, pero eso no lo detiene llamando al ConvertFrom. ¿Tiene un ejemplo completo (tal vez basado en lo siguiente) que lo muestra no llamando al 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); 
     } 
    } 
} 
Cuestiones relacionadas