Pregunta

Estoy utilizando un PropertyGrid para mostrar las propiedades de mis objetos. Sin embargo, también estoy permitiendo al usuario crear sus propias propiedades, y establecer valores para estas propiedades personalizadas. Cada objeto que puede tener estas propiedades personalizadas tiene una colección diccionario, donde la cadena es una clave única para identificar la propiedad, y el objeto es el valor de un tipo primitivo (cadena, int, int, etc ..)

He creado un PropertyDescriptor medida con métodos get y que comprueban el diccionario para una llave adecuada, o que crean / se sustituye el valor con una clave que coincida respectivamente SET.

Sin embargo, también quiero dar al usuario la posibilidad de limpiar la propiedad, y por lo tanto eliminar su entrada del diccionario completo. Me gustaría poner el código para que este en el método de reemplazo ResetValue de mi PropertyDescriptor costumbre, sin embargo, no veo ninguna manera a través de la interfaz de PropertyGrid a envoke esto? No parece ser una opción del menú contextual o algo obvio como eso.

Así que si tengo una PropertyDescriptor personalizado con un método ResetValue costumbre, ¿cómo realmente evocar ese método desde un PropertyGrid?

¿Fue útil?

Solución

Creo que la forma más fácil de lograr esto es agregar un menú contextual a la cuadrícula de propiedades, con un elemento de menú "Reset", y luego el manejo de su evento de clic como esto:

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

Creo Visual Studio hace algo como esto.

Otros consejos

Anotación: El PropertyGrid.SelectedObject devuelve el valor incorrecto (componente) en Childobjects. En consecuencia, el Método CanResetValue recived un componente incorrecto.

Mi Solución:

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

Para los objetos secundarios de la referencia al objeto que contiene una propiedad que está oculto en la propiedad de los descendientes Instance no públicos de la clase GridItem. Afortunadamente, esta propiedad es un miembro de la interfaz ITypeDescriptorContext cual estas clases descendientes no implementan. Por lo tanto, hay una solución que incluye correcta habilitación del comando Reset en un menú contextual para todas las propiedades:

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();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top