在System.Windows.Forms.PropertyGrid控件中使用自定义PropertyTab

时间:2011-09-28 18:50:00

标签: .net propertygrid custom-attributes

我正在尝试使用WinForms PropertyGrid控件的可自定义属性选项卡功能,但它让我被打败了。我特意尝试在运行时使用PropertyGrid来显示对象属性,而不是尝试为控件创建设计时支持,尽管它们似乎是类似技术的应用程序。

这个问题让我很困惑。我试图关注这个主题的几个教程,但没有一个得出任何真正可靠的结论。

文献综述

http://msdn.microsoft.com/en-us/library/aa302334.aspx#vsnetpropbrow_topic05

本文告诉读者,添加属性选项卡很容易,并且代码示例位于包含的FunkyButton项目中,不包含在任何地方。

http://www.codeproject.com/KB/grid/PropertyGridExWinForms.aspx

此项目建议使用自定义属性选项卡的唯一方法是通过覆盖例如GetService()私有方法来扩展基本属性网格功能。我确信这不是必需的,并试图使用其信息来创建服务提供者。但它确实告诉我,属性网格中SelectedObject的类需要将类属性PropertyTabAttribute分配给我创建和使用的扩展System.Windows.Forms.PropertyGridInternal.PropertiesTab。

http://www.dacris.com/blog/2008/01/02/net-how-to-show-events-tab-in-a-property-grid/

本文指出属性网格本身需要使用PropertyGrid.PropertyTabs.AddTabType()方法添加选项卡。然后它显示属性网格的Site属性需要分配,然后沾沾自喜地暗示我应该已经知道如何执行此操作:“...您需要将网格的Site属性设置为您已经设置的某个设计站点如果您正在托管自己的设计师,您应该知道如何检索它。“

http://www.syncfusion.com/FAQ/windowsforms/faq_c83c.aspx#q913q

在开始撰写这个问题时,我找到了一篇关于该主题的简短文章的链接,其中包含了代码。这个项目在设计时功能上看起来更加专注,但是当我在一个完全普通的PropertyGrid中使用它们的对象实例时,它显示了Properties选项卡按钮和它们的Custom Tab对象。我能够毫不费力地在相关视图之间切换。但是,该项目似乎建议现在需要自定义属性来区分可用视图之间的属性。本文现在建议我忽略网站定义,专门的PropertyGrids和服务提供者,并专注于显示的对象本身。

令人沮丧的是,在修改此项目以更接近我的应用程序时,我将操作属性网格移动到选项卡控件的标签页,其中它破坏了属性网格显示默认属性选项卡的能力,因此意味着我可以切换到自定义属性选项卡,但永远不会回来。

结论

我完全失败了。我必须接近,但在我尝试使这项工作的所有途径中,也许我的大脑只是被炒了。使属性标签工作的关键是什么? 是吗:

  • PropertyGrid.SelectedObject的特定类定义?
  • 属性网格本身的设置?
  • 关于自定义标签定义的所有内容?

最后描述的项目是否有效,因为SelectedObject继承自UserControl? SelectedObject是否需要从System.ComponentModel.Component?

继承

如果有人可以尝试清除这一切,并提供最简洁的描述如何使其发挥作用,我将非常感激。

非常感谢。

3 个答案:

答案 0 :(得分:2)

以下是自定义属性标签的代码:

public class CustomTab : PropertyTab
{
    private Bitmap _bitmap;

    // the tooltip displayed in the grid
    public override string TabName
    {
        get
        {
            return "CustomTab";
        }
    }

    // the icon displayed in the grid
    public override Bitmap Bitmap
    {
        get
        {
            if (_bitmap == null)
            {
                // 1. create a file named "CustomTab.bmp". It must be a 16x16, 8-bit bitmap. Transparency pixel is magenta.
                // 2. place it in the project aside this .cs
                // 3. configure its build action to "Embedded Resource"
                _bitmap = new Bitmap(GetType(), GetType().Name + ".bmp");
            }
            return _bitmap;
        }
    }

    // TODO: return the descriptor corresponding to the properties you want to show
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object component, Attribute[] attributes)
    {
        return new PropertyDescriptorCollection(null);
    }

    public override PropertyDescriptorCollection GetProperties(object component, Attribute[] attributes)
    {
        return GetProperties(null, component, attributes);
    }
}

以下是如何将其添加到属性网格中:

CustomTab tab = new CustomTab();
grid.PropertyTabs.AddTabType(typeof(CustomTab), PropertyTabScope.Global);

它不显示任何内容,因为我没有在GetProperties重载中返回任何PropertyDescriptor,但是您需要定义要使用的描述符。

OP编辑:

看来,制作属性标签的关键在于解决网络上可用信息的混乱:

  • 显示的对象不需要继承Control或Component

  • 之类的东西
  • 无需设置PropertyGrid.Site属性

  • 无需使用自定义类

  • 扩展属性网格
  • 如果属性网格在SelectedObject中被调出,则属性网格甚至不需要显式添加标签。当然,需要添加持久性标签。

  • 确保覆盖所有三个PropertiesTab.GetProperties方法,并指向所需的方法而不是基本方法。

  • 标签的位图覆盖必须实际执行某些操作!

答案 1 :(得分:0)

代码示例现已在您在说明中提及的MSDN page上提供。下载链接位于“摘要”和“内容”之间;搜索“Codesamples.exe”可能会很快带你去那里。

答案 2 :(得分:0)

我认为来自MSDN的示例代码已经足够了:

Form地方放置一个PropertyGrid。 编译示例代码时,VS工具箱中会出现一个组件。将其放在表单上并在属性窗口中,将其设置为PropertyGrid.SelectedObject属性。

BTW,实际的自定义发生在PropertyTab::GetProperties