【问题标题】:Using Custom PropertyTab in System.Windows.Forms.PropertyGrid Control在 System.Windows.Forms.PropertyGrid 控件中使用自定义 PropertyTab
【发布时间】:2011-09-28 18:50:00
【问题描述】:

我正在尝试使用 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?

如果有人可以尝试清除这一切并提供最简洁的说明来说明如何使其工作,我将不胜感激。

非常感谢。

【问题讨论】:

  • 附加信息,最后一个引用的项目似乎工作,因为 SelectedObject 是一个 Windows.Forms.Control 并且它被添加到窗体的 Corm.Controls.ControlCollection 上形式。它在显示“属性”选项卡方面的变化无常,这与它和选项卡控件被添加到构造函数中的 ControlCollection 的顺序有关。如果在表单的 InitializeComponents() 方法中的选项卡控件之后添加它,则它可以工作。

标签: .net propertygrid custom-attributes


【解决方案1】:

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

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 编辑​​:

似乎使属性选项卡起作用的关键是消除网络上可用信息的混乱:

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

  • 无需设置 PropertyGrid.Site 属性

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

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

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

  • 选项卡的位图覆盖实际上必须做一些事情!

【讨论】:

  • 哇,这是出乎意料的。在我的 PropertyTab 覆盖中,我完全忽略了 Bitmap 属性覆盖,将其保留为默认的 MyBase.Bitmap (base.Bitmap),期望调用一些默认图标就足够了。我将尝试使用我学到的内容对您的帖子进行编辑,以便将其标记为已解决。
【解决方案2】:

您在描述中提到的MSDN page 上现在提供了代码示例。下载链接位于“摘要”和“目录”之间;搜索“Codesamples.exe”可能会很快带您到那里。

【讨论】:

    【解决方案3】:

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

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

    顺便说一句,实际的定制发生在PropertyTab::GetProperties。

    【讨论】:

      猜你喜欢
      • 2011-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多