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

.net 在System.Windows.Forms.PropertyGrid控件中使用自定义PropertyTab,.net,propertygrid,custom-attributes,.net,Propertygrid,Custom Attributes,我正试图使用WinForms PropertyGrid控件的可自定义属性选项卡功能,但它让我失败了。我特别尝试在运行时使用PropertyGrid来显示对象属性,而不是尝试为控件创建设计时支持,尽管它们似乎是类似技术的应用程序 这个问题把我弄糊涂了。我尝试了几篇关于这个主题的教程,但都没有得出任何真正可靠的结论 文献综述 本文告诉读者,添加属性选项卡是很容易做到的,并且代码示例包含在包含的FunkyButton项目中,而不包含在任何地方 此项目建议使用自定义属性选项卡的唯一方法是通过覆盖例如

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

这个问题把我弄糊涂了。我尝试了几篇关于这个主题的教程,但都没有得出任何真正可靠的结论

文献综述

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

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

本文指出,属性网格本身要求使用PropertyGrid.PropertyTabs.AddTabType()方法添加选项卡。然后,它显示需要分配属性网格的站点属性,然后自鸣得意地建议我应该已经知道如何执行此操作:“……您需要将网格的站点属性设置为已实现的某个设计器站点。如果您托管自己的设计器,您应该知道如何检索此属性。”

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

令人沮丧的是,在修改此项目以更接近地反映我的应用程序时,我将操作属性网格移动到了选项卡控件的选项卡页面,在该页面中,属性网格无法显示默认属性选项卡,这意味着我可以切换到自定义属性选项卡,但决不能返回

结论

我完全不知所措。我一定很接近,但在我尝试过的所有方法中,也许我的大脑已经崩溃了。使属性选项卡工作的关键是什么? 是:

  • PropertyGrid.SelectedObject的特定类定义
  • 属性网格本身的设置
  • 关于自定义选项卡定义的所有内容
上一个描述的项目是否仅因为SelectedObject继承自UserControl而起作用?所选对象是否需要从System.ComponentModel.Component继承

如果有人能把这一切弄清楚,并尽可能简洁地描述如何使它发挥作用,我将不胜感激


非常感谢。

以下是自定义属性选项卡的代码:

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,但您需要在这里定义要使用的描述符

操作编辑:

看来,使属性选项卡正常工作、消除web上可用信息混乱的关键在于:

  • 显示的对象不需要继承控件或组件之类的内容

  • 不需要设置PropertyGrid.Site属性

  • 属性网格不需要使用自定义类进行扩展

  • 如果属性在SelectedObject中调用该选项卡,则属性网格甚至不需要显式添加该选项卡。当然,需要添加一个持久性选项卡

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

  • 选项卡的位图覆盖必须实际执行某些操作


代码示例现在可以在您在说明中提到的上找到。下载链接位于“摘要”和“内容”之间;搜索“Codesamples.exe”可能会让您很快到达目的地。

我认为中的示例代码已经足够了:

表单上
放置PropertyGrid。 编译示例代码时,VS工具箱中会出现一个组件。将其放在窗体上,并在属性窗口中,将其设置为
PropertyGrid。选择对象
property


顺便说一句,实际自定义发生在
PropertyTab::GetProperties

其他信息中,最后一个引用的项目似乎可以工作,因为所选对象是Windows.Forms.Control,并且正在将其添加到表单的Corm.Controls.ControlCollection中。它在显示Properties选项卡方面的易变性与它和tabcontrol在构造函数中添加到ControlCollection的顺序有关。如果它添加到表单的InitializeComponents()方法中的tab控件之后,它就会工作。哇,这是出乎意料的。在我的PropertyTab覆盖中,我完全忽略了位图属性覆盖,将其保留为默认的MyBase.Bitmap(base.Bitmap),希望调用一些默认图标就足够了。我将尝试添加一个编辑到您的文章与我的