5

我正在使用 PropertyGrid 来显示我的对象的属性。但是,我还允许用户创建自己的属性,并为这些自定义属性设置值。每个可以具有这些自定义属性的对象都有一个 Dictionary 集合,其中字符串是标识属性的唯一键,Object 是原始类型(字符串、布尔值、整数等)的值。

我用 get 和 set 方法创建了一个自定义 PropertyDescriptor,这些方法检查 Dictionary 是否有匹配的键,或者分别用匹配的键创建/覆​​盖值。

但是,我还想让用户能够清除该属性,从而将其条目从字典中完全删除。我将代码放在我的自定义 PropertyDescriptor 的 ResetValue 覆盖方法中,但是我看不到任何通过 PropertyGrid 接口调用它的方法?它似乎不是上下文菜单选项或类似的东西。

因此,如果我有一个带有自定义 ResetValue 方法的自定义 PropertyDescriptor,我如何真正从 PropertyGrid 调用该方法?

4

4 回答 4

3

我认为实现这一点的最简单方法是在属性网格中添加一个上下文菜单,带有一个菜单项“重置”,然后像这样处理它的点击事件:

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

我认为 Visual Studio 会做这样的事情。

于 2009-04-13T18:29:43.183 回答
2

注解:PropertyGrid.SelectedObject 在 Childobjects 中返回了错误的 Value(组件)。因此,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();
}
于 2013-05-11T14:22:06.333 回答
0

对于子对象,对包含属性的对象的引用隐藏在类Instance的非公共后代的属性中GridItemITypeDescriptorContext值得庆幸的是,这个属性是这些后代类确实实现的接口的成员。因此,有一个解决方案包括在所有属性的上下文菜单中正确启用重置命令:

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();
}
于 2018-03-11T11:24:41.137 回答
0

这就是我用来重置我的属性的方法

    public static void InitResetContextMenuStrip(this PropertyGrid grid, params string[] resettableProperties)
    {
        if (grid.ContextMenuStrip != null)
            return;

        var menuStrip = new ContextMenuStrip();
        var resetItem = new ToolStripMenuItem("Reset");

        resetItem.Click += (s, e) =>
        {
            try
            {
                if (resettableProperties.Any(p => grid.SelectedGridItem.PropertyDescriptor.Name == p))
                {
                    grid.SelectedGridItem.PropertyDescriptor.SetValue(grid.SelectedObject, null);
                    grid.Refresh(); //redraw the grid to reflect the changes
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        };

        menuStrip.Items.Add(resetItem);

        menuStrip.Opening += (s, e) =>
        {
            try
            {
                resetItem.Enabled = resettableProperties.Any(p => grid.SelectedGridItem.PropertyDescriptor.Name == p);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        };

        grid.ContextMenuStrip = menuStrip;
    }

这就是我使用它的方式:

myGrid.InitResetContextMenuStrip(
    nameof(ClassName.PropertyName1),
    nameof(ClassName.PropertyName2));

信用: http: //www.windows-tech.info/3/41955b2a405bf481.php

于 2021-02-24T12:09:46.120 回答