Сброс свойств из сетки свойств
-
09-09-2019 - |
Вопрос
Я использую PropertyGrid для отображения свойств моих объектов.Однако я также разрешаю пользователю создавать свои собственные свойства и устанавливать значения для этих настраиваемых свойств.Каждый объект, который может иметь эти настраиваемые свойства, имеет коллекцию Dictionary, где строка — это уникальный ключ для идентификации свойства, а Object — это значение примитивного типа (string, bool, int и т. д.).
Я создал собственный PropertyDescriptor с методами get и set, которые проверяют словарь на наличие соответствующего ключа или создают/перезаписывают значение соответствующим ключом соответственно.
Однако я также хочу дать пользователю возможность очистить свойство и, таким образом, полностью удалить его запись из словаря.Я бы поместил код для этого в метод переопределения ResetValue моего пользовательского PropertyDescriptor, однако я не вижу никакого способа через интерфейс PropertyGrid вызвать это?Кажется, это не опция контекстного меню или что-то очевидное в этом роде.
Итак, если у меня есть собственный PropertyDescriptor с собственным методом ResetValue, как мне на самом деле вызвать этот метод из PropertyGrid?
Решение
Я думаю, что самый простой способ добиться этого — добавить контекстное меню в сетку свойств с пунктом меню «Сброс», а затем обработать событие щелчка следующим образом:
private void resetToolStripMenuItem_Click(object sender, EventArgs e)
{
PropertyDescriptor pd = propGrid.SelectedGridItem.PropertyDescriptor;
pd.ResetValue(propGrid.SelectedObject);
}
Я думаю, что Visual Studio делает что-то подобное.
Другие советы
Аннотация: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();
}
Для дочерних объектов ссылка на объект, содержащий свойство, скрыта в 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();
}