Reimpostazione di proprietà di una griglia delle proprietà
-
09-09-2019 - |
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?
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();
}