pourquoi someclass.classfield.tructfield code> Propriété ne change pas dans un
PropertyGrid code>?
Il semble que
PropertyGrid code> n'appelle pas
someclass.classfield.set code> après
sinistress code> instance a été modifié. Mais le même code fonctionne bien avec
point code> au lieu de
somestract code>.
[TypeConverter(typeof(ExpandableObjectConverter))]
public struct SomeStruct
{
private int structField;
public int StructField
{
get
{
return structField;
}
set
{
structField = value;
}
}
public override string ToString()
{
return "StructField: " + StructField;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class SomeClass
{
public SomeStruct ClassField
{
get;
set;
}
}
...
var someClass = new SomeClass
{
ClassField = new SomeStruct
{
StructField = 42
}
};
propertyGrid.SelectedObject = someClass;
3 Réponses :
Vous avez besoin d'un type de typonverter spécial qui remplace tyconverter.gecreateInstancesupported car sinon La magie Copy-By-Value / Boxing se produit derrière la scène de la manière dont la grille de propriété gère tout cela.
Voici un élément qui devrait fonctionner pour la plupart des types de valeur. Vous le déclarez comme ceci: p>
[TypeConverter(typeof(ValueTypeTypeConverter<SomeStruct>))] public struct SomeStruct { public int StructField { get; set; } } public class ValueTypeTypeConverter<T> : ExpandableObjectConverter where T : struct { public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) { return true; } public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) { if (propertyValues == null) throw new ArgumentNullException("propertyValues"); T ret = default(T); object boxed = ret; foreach (DictionaryEntry entry in propertyValues) { PropertyInfo pi = ret.GetType().GetProperty(entry.Key.ToString()); if (pi != null && pi.CanWrite) { pi.SetValue(boxed, Convert.ChangeType(entry.Value, pi.PropertyType), null); } } return (T)boxed; } }
J'ai modifié la réponse de Simon Mourier pour éviter que le besoin d'appréciation d'appréciation est un générique:
Dans mon cas, l'argument générique n'est pas connu au moment de la compilation (structure d'options pour un plugin). Vous pouvez obtenir une copie de la valeur actuelle à l'aide de context.propertydescriptor.getvalue (context.Instance); code>:
Les structures sont censées être immuables
Celui-ci est mutable. Même chose que point / rectangle / etc.
Bon point (caractères supplémentaires)
Notez le mot "objet" dans "expanstableObjectConverter". Vous allez modifier une copie en boîte de la structure, elle ne se propage pas. Utilisez la mise en œuvre de PointConverter à titre d'exemple.
@Hans Passant, merci beaucoup, ça marche.