2010-01-22 9 views
5

Solo il metodo ConvertTo viene chiamato (un sacco di volte) quando accede al propertygrid. Questo restituisce correttamente "Foo!" stringa nel propertygrid. Quando faccio clic per modificare ottengo un'eccezione Cannot convert object of type Foo to type System.String. (non esattamente, tradotto). Il metodo ConvertFrom non viene chiamato, nessun indizio perché? E l'errore indica che sta cercando di convertire in una stringa, non da.TypeConverter in propertygrid converte solo da stringa, non in

Penso che quando voglio modificare questo oggetto, deve convertire da Foo a stringa, e una volta terminata la modifica. Classe

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

proprietà a cui si accede:

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

ho scoperto che ha qualcosa a che fare con la MultilineStringEditor, se rendo invalido questo, funziona correttamente –

+0

Ho appena visto il tuo aggiornamento; dovrai scrivere il tuo editor - 'MultilineStringEditor' ** non ** saprà come elaborare un' Foo', quindi sta dicendo "no", o un'eccezione viene sollevata e gestita. –

risposta

5

Re l'aggiornamento; ecco una FooEditor che dovrebbe funzionare come spessore:

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

Avrete ovviamente bisogno di associarlo:

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

Sembra farlo, grazie! Stavo pensando che potrei usare ENTRAMBI un UITypeEditor e un TypeConverter. –

+0

@Robert - puoi ancora ;-p Non dimenticare alcuni altri controlli ('DataGridView' ecc.) Userà solo il convertitore, non l'editor. –

0

non può riprodurre; funziona bene per me; dovresti provare il destinationType e il tipo di value, btw - ma questo non lo ferma chiamandolo ConvertFrom. Avete un esempio completo (forse basato su quanto segue) che lo mostra non chiamando 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); 
     } 
    } 
} 
Problemi correlati