Domanda

Io sto usando una PropertyGrid per visualizzare le proprietà da i miei oggetti.Tuttavia, io sono, inoltre, permette all'utente di creare la loro proprietà, e impostare i valori di queste proprietà personalizzate.Ogni oggetto può avere queste proprietà personalizzate è una raccolta di dizionari, in cui la stringa è una chiave univoca per identificare la proprietà, e l'Oggetto è il valore di un tipo primitivo (string, bool, int, ecc..)

Ho creato un custom PropertyDescriptor con metodi get e set per controllare il Dizionario per una chiave di corrispondenza, o creare/sovrascrivere il valore di con una chiave corrispondente, rispettivamente.

Tuttavia, voglio anche dare all'utente la possibilità di cancellare la proprietà, e quindi rimuovere la voce da dizionario del tutto.Avevo messo il codice per questo nel ResetValue metodo di sostituzione della mia custom PropertyDescriptor, tuttavia non riesco a vedere alcun modo con l'PropertyGrid interfaccia envoke questo?Non sembra essere un'opzione del menu contestuale o qualcosa di ovvio come che.

Quindi, se ho un custom PropertyDescriptor con un costume ResetValue metodo, come faccio effettivamente evocare il metodo da un PropertyGrid?

È stato utile?

Soluzione

Credo che il modo più semplice per raggiungere questo obiettivo è quello di aggiungere un menu contestuale alla griglia delle proprietà, con una voce di menu "Reset", e quindi la gestione l'evento click in questo modo:

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

Credo che Visual Studio fa qualcosa del genere.

Altri suggerimenti

della nota: Il PropertyGrid.SelectedObject restituisce il valore errato (componente) in Childobjects. Di conseguenza il metodo CanResetValue recived un componente non corretto.

La mia soluzione:

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

Per gli oggetti figlio il riferimento all'oggetto che contiene una proprietà è nascosto nel Instance proprietà di non-pubblico discendenti dei GridItem classe.Per fortuna, questa proprietà è un membro della ITypeDescriptorContext interfaccia che questi discendente classi implementano.Così, c'è una soluzione che comprende corretta attivazione del comando di Reset nel menu contestuale di tutte le proprietà:

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();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top