从属性网格重置属性

时间:2009-04-13 17:53:38

标签: c# propertygrid propertydescriptor

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

我创建了一个自定义PropertyDescriptor,其中包含get和set方法,用于检查Dictionary以查找匹配的键,或者分别使用匹配的键创建/覆​​盖该值。

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

因此,如果我有一个带有自定义ResetValue方法的自定义PropertyDescriptor,我如何从PropertyGrid中实际唤起该方法?

4 个答案:

答案 0 :(得分:3)

我认为最简单的方法是在属性网格中添加一个contextmenu,菜单项为“Reset”,然后像这样处理它的click事件:

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

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

答案 1 :(得分: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();
}

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

这是我用来重置我的属性

    server {
        listen  80;

        return 301 https://$host$request_uri;

        include  "/opt/bitnami/nginx/conf/bitnami/*.conf";


        location /page/ {
                rewrite id/(.*)$ /home/page/index.php?id=$1 last;
        }

        location /status {
            stub_status on;
            access_log   off;
            allow 127.0.0.1;
            deny all;
        }
    }
    server {
        listen 443 ssl;
        location /page/ {
                rewrite id/(.*)$ /home/page/index.php?id=$1 last;
        }
    }

这就是我使用它的方式:

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

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