Sto analizzando la fattibilità di usare la PropertyGrid per editare degli oggetti la cui descrizione sta in un file XML.
A parte la non immediata conversione di un oggetto da XML a "true" object (e qui prevedo parecchio CodeDomming...) mi sono ritrovato alcuni "dettagli" che la PropertyGrid e il meccanismo di reflection che la accompagna non consentono di realizzare in maniera semplice ed immediata.

  • Mostrare gli items secondo un ordine "custom" e non alfabetico o categorizzato
  • Modificare lo status di read-only di un item a runtime
  • Aggiungere un unità di misura al valore dell'item (es: 1.5 €)

Dopo varie analisi sono giunto alla soluzione implementando ICustomTypeDescriptor e creando un custom property descriptor.
Le righe di codice sono parecchie (spesso dei semplici rimandi all'uso di TypeDescriptor), la parte più interessante  è l'implementazione di ICustomTypeDescriptor.GetProperties 

PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] filter)
{
PropertyDescriptorCollection baseProps = TypeDescriptor.GetProperties(GetType(), filter);
//Custom sort order 
baseProps=baseProps.Sort(new string[]{"Index","Age","Name"});
PropertyDescriptor[] newProps = new PropertyDescriptor[baseProps.Count];
for (int i = 0; i < baseProps.Count; i++)
{
PropertyDescriptor prop=baseProps[i];
if(prop.DisplayName!="Index")
 
newProps[i]=new CustomDescriptor(prop,filter,false);
else
newProps[i]=new CustomDescriptor(prop,filter,this.Name=="MyTest");
}
return new PropertyDescriptorCollection(newProps);
}

Fondamentalmente ridefinisco le caratteristiche delle varie properties prima che queste vengano passate alla PropertyGrid, in particolare faccio il sort delle stesse secondo un mio ordine (Index,Age,Name) dopodichè ricreo un nuovo Array di PropertyDescriptors usando un CustomDescriptor che mi permette di personalizzare lo status ReadOnly in base alla proprietà Name del mio oggetto (ma la logica di impostazione potrebbe essere completamente diversa...)

public class CustomDescriptor : PropertyDescriptor 
 { 
  private PropertyDescriptor baseProp; 
  private bool _mode; 
  public CustomDescriptor(PropertyDescriptor baseProp, Attribute[] filter,bool mode): base(baseProp) 
  { 
   _mode=mode;
     this.baseProp = baseProp;
  }

  public override bool IsReadOnly 
  { 
   get {return _mode;} 
  } 
  ...
 }

Chiaramente le proprietà interessate devono essere decorate con [RefreshProperties(RefreshProperties.Repaint)] in modo fa forzare la reinvocazione della GetProperties().

... per l'unità di misura..., basta usare un custom TypeConverter e il gioco è fatto.
Nel mio caso ho implementato ICustomTypeDescriptor in quanto la customizzazione deve avvenire a runtime, nel caso si debba applicare la stessa tecnica ad un controllo standard si può considerare la possibilità di implementare il tutto in un custom designer.
Nulla di che..., ma in alcuni casi certe informazioni sono abbastanza difficili da reperire...