Сброс свойств из сетки свойств - PullRequest
5 голосов
/ 13 апреля 2009

Я использую PropertyGrid для отображения свойств из моих объектов. Тем не менее, я также позволяю пользователю создавать свои собственные свойства и устанавливать значения для этих пользовательских свойств. Каждый объект, который может иметь эти пользовательские свойства, имеет коллекцию Dictionary, где строка - это уникальный ключ для идентификации свойства, а Object - значение примитивного типа (string, bool, int и т. Д.)

Я создал собственный PropertyDescriptor с методами get и set, которые проверяют Словарь на наличие соответствующего ключа или создают / перезаписывают значение соответствующим ключом соответственно.

Однако я также хочу дать пользователю возможность очистить свойство и, таким образом, полностью удалить его запись из словаря. Я бы добавил к этому код в методе переопределения ResetValue моего пользовательского PropertyDescriptor, однако я не вижу способа через интерфейс PropertyGrid вызвать это? Кажется, это не пункт контекстного меню или нечто подобное.

Итак, если у меня есть собственный PropertyDescriptor с пользовательским методом ResetValue, как я могу вызвать этот метод из PropertyGrid?

Ответы [ 3 ]

3 голосов
/ 13 апреля 2009

Я думаю, что самый простой способ добиться этого - добавить контекстное меню в вашу сетку свойств с помощью пункта меню «Сброс», а затем обработать событие click следующим образом:

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

Я думаю, Visual Studio делает что-то подобное.

2 голосов
/ 11 мая 2013

Примечание: PropertyGrid.SelectedObject возвращает неправильное значение (компонент) в дочерних объектах. Следовательно, метод CanResetValue получил неправильный компонент.

Мое решение:

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();
}
0 голосов
/ 11 марта 2018

Для дочерних объектов ссылка на объект, содержащий свойство, скрыта в свойстве Instance непубличных потомков класса GridItem. К счастью, это свойство является членом интерфейса ITypeDescriptorContext, который реализуют эти классы-потомки. Итак, есть решение, которое включает правильное включение команды «Сброс» в контекстном меню для всех свойств:

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