Question

J'utilise un PropertyGrid pour afficher les propriétés de mes objets. Cependant, je permet également à l'utilisateur de créer leurs propres propriétés et définir des valeurs pour ces propriétés personnalisées. Chaque objet qui peut avoir ces propriétés personnalisées a une collection Dictionnaire, où la chaîne est une clé unique pour identifier la propriété, et l'objet est la valeur d'un type primitif (string, bool, int etc ..)

J'ai créé un PropertyDescriptor personnalisé avec get et set méthodes qui vérifient le dictionnaire pour une clé correspondante, ou créer / remplacer la valeur avec une clé correspondant respectivement.

Mais je veux aussi donner à l'utilisateur la possibilité de supprimer la propriété, et supprimez son entrée dans le dictionnaire entièrement. Je mettrais le code à cela dans la méthode de remplacement ResetValue de mon PropertyDescriptor sur mesure, mais je ne vois pas comment à travers l'interface PropertyGrid pour envoke cela? Il ne semble pas être une option de menu contextuel ou quelque chose d'évident comme ça.

Donc, si j'ai un PropertyDescriptor personnalisé avec une méthode ResetValue sur mesure, comment puis-je évoquer en fait cette méthode à partir d'un PropertyGrid?

Était-ce utile?

La solution

Je pense que la meilleure façon d'y parvenir est d'ajouter un contextmenu à votre grille de propriété, avec un élément de menu « Reset », et la manipulation puis son événement click comme celui-ci:

private void resetToolStripMenuItem_Click(object sender, EventArgs e)
{                        
    PropertyDescriptor pd = propGrid.SelectedGridItem.PropertyDescriptor;
    pd.ResetValue(propGrid.SelectedObject);
}

Je pense que Visual Studio fait quelque chose comme ça.

Autres conseils

Annotation: Le PropertyGrid.SelectedObject renvoie la valeur erronée (composant) dans ChildObjects. Par conséquent, la méthode CanResetValue recived un composant incorrect.

Ma solution:

private void OnContextMenuOpening(object sender, CancelEventArgs e)
{
  var lGrid = mCurrentControl as PropertyGrid;

  if (lGrid != null)
  {
    var lItem = lGrid.SelectedGridItem;

    // Für untergeordnete Eigenschaften kann nicht SelectedObject verwendet werden
    // Component ist eine interne Eigenschaft der Klasse System.Windows.Forms.PropertyGridInternal.GridEntry
    // ((System.Windows.Forms.PropertyGridInternal.GridEntry)(lItem)).Component
    // Zugriff via Reflection
    var lComponent = lItem.GetType().GetProperty("Component").GetValue(lItem, null);

    if (lComponent != null)
      tsmi_Reset.Enabled = lItem.PropertyDescriptor.CanResetValue(lComponent);
    else
      tsmi_Reset.Enabled = lItem.PropertyDescriptor.CanResetValue(lGrid.SelectedObject);
  }
}

// Contextmenu -> Reset
private void OnResetProperty(object sender, EventArgs e)
{
  var lGrid = mCurrentControl as PropertyGrid;

  if (lGrid != null)
    lGrid.ResetSelectedProperty();
}

Pour les enfants objets de la référence à l'objet contenant une propriété est cachée dans la propriété Instance des descendants non publiques de la classe GridItem. Heureusement, cette propriété est membre de l'interface qui ITypeDescriptorContext ces classes descendantes ne mettent en œuvre. Donc, il y a une solution qui inclut correcte permettant de la commande de réinitialisation dans un menu contextuel pour toutes les propriétés:

private void contextMenuToolStrip_Opening(object sender, CancelEventArgs e)
{
  var item = propertyGrid.SelectedGridItem;
  resetToolStripMenuItem.Enabled = item != null &&
                                   item.GridItemType == GridItemType.Property &&
                                   item is ITypeDescriptorContext context &&
                                   item.PropertyDescriptor.CanResetValue(context.Instance);
}

private void resetToolStripMenuItem_Click(object sender, EventArgs e)
{
  propertyGrid.ResetSelectedProperty();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top