我正在尝试使用 WinForms PropertyGrid 控件的可自定义属性选项卡功能,但它让我失败了。我特别尝试在运行时使用 PropertyGrid 来显示对象属性,而不是尝试为控件创 build 计时支持,尽管它们似乎是类似技术的应用程序。
这个问题让我很困惑。我尝试遵循有关该主题的几个教程,但没有一个得出任何真正可靠的结论。
文献综述
http://msdn.microsoft.com/en-us/library/aa302334.aspx#vsnetpropbrow_topic05
本文告诉读者,添加属性选项卡是很容易做到的,并且代码示例位于包含的 FunkyButton 项目中,但未包含在任何地方。
http://www.codeproject.com/KB/grid/PropertyGridExWinForms.aspx
该项目建议使用自定义属性选项卡的唯一方法是通过覆盖例如 GetService() 私有(private)方法来扩展基本属性网格功能。我非常确定这不是必需的,并尝试使用其信息来创建服务提供商。然而,它确实启发了我,属性网格中的 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 中使用其对象的实例时,它显示了“属性”选项卡按钮及其“自定义选项卡”对象。我能够毫不费力地在相关 View 之间切换。然而,该项目似乎建议现在需要自定义属性来区分可用 View 之间的属性。本文现在建议我忽略站点定义、专门的 PropertyGrid 和服务提供商,而专注于显示的对象本身。
令人沮丧的是,在修改此项目以更准确地反射(reflect)我的应用程序时,我将操作属性网格移至选项卡控件的选项卡页,其中它破坏了属性网格显示默认属性选项卡的能力,因此这意味着我可以切换到自定义属性选项卡,但永远不会返回。
结论
我完全迷失了。我一定很接近了,但在我尝试过的所有途径中,也许我的大脑只是被烧坏了。使属性选项卡发挥作用的关键是什么? 是吗:
- PropertyGrid.SelectedObject的具体类定义?
- 属性网格本身的设置?
- 关于自定义选项卡定义的所有信息?
最后描述的项目是否仅因为 SelectedObject 继承自 UserControl 才有效? SelectedObject是否需要继承自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,但您需要在此处定义要使用的描述符。
操作编辑:
看来使属性选项卡发挥作用的关键在于消除网络上可用信息的困惑:
显示的对象不需要继承诸如 Control 或 Component 之类的东西
无需设置 PropertyGrid.Site 属性
属性网格不需要使用自定义类进行扩展
如果属性在 SelectedObject 中调用选项卡,则属性网格甚至不需要显式添加选项卡。当然,需要添加一个持久选项卡。
确保所有三个 PropertiesTab.GetProperties 方法都被重写并指向所需的方法而不是基本方法。
选项卡的位图覆盖实际上必须执行某些操作!
关于.net - 在 System.Windows.Forms.PropertyGrid 控件中使用自定义 PropertyTab,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7588027/