C# 如何在PropertyGrid中插入EventsTab?

C# 如何在PropertyGrid中插入EventsTab?,c#,.net,winforms,visual-studio,collections,C#,.net,Winforms,Visual Studio,Collections,这里是交易,我有一些集合要插入到一个验证类中,我正试图使它能够插入到Visual Studio编辑器的IDE中,并解释所有上下文(如果不够,请询问我),我希望PropertyGrid在Visual Studio的IDE中显示它的EventsTab 但问题是,我已经检查了,我发现为了插入EventsTab的按钮,我们必须调用ShowEventsButton(true)属性网格的私有方法,但该方法不起作用(称为反射) 所以到目前为止我所尝试的。。。 使用参数调整AddRefTab传递EventsT

这里是交易,我有一些集合要插入到一个验证类中,我正试图使它能够插入到Visual Studio编辑器的IDE中,并解释所有上下文(如果不够,请询问我),我希望PropertyGrid在Visual Studio的IDE中显示它的EventsTab

但问题是,我已经检查了,我发现为了插入EventsTab的按钮,我们必须调用
ShowEventsButton(true)
属性网格的私有方法,但该方法不起作用(称为反射)

所以到目前为止我所尝试的。。。
  • 使用参数调整AddRefTab传递EventsTab(私有方法)
  • 使用true参数调用SetupToolbar(私有方法)
  • 调用刷新选项卡
  • 将所有工具提示设置为可见
  • 调用ShowEventsButton(true)

编辑 我在这个模式中有两个类,其中一个是从IValidation接口继承的Validation类,它包含我想在propertyGrid中显示的事件 另一个类是ControlValidator,它派生自一个组件,并有一个验证列表

编辑2 更具体地说,我试图实现的是在这个CollectionEditor中使用CollectionEditor(与编辑DataGridView合谋的窗口相同),我想让它在其PropertyGrid中显示EventsTab(实际上我想让它与VisualStudioIDE的PropertyTab完全一样,但我还不在这一部分)所以我想展示的事件和属性是ControlValidator(组件)的列表/集合

让我试着说得更清楚些 正如您所见,控件验证器有一个IValidation接口的集合,它是组件,因此它应该并且正在这样工作 正如您所看到的,它没有在IDE中显示events选项卡,因为它没有任何事件,但是如果双击controlValidator的Validations属性,它将打开CollectionEditor,其中包含PropertyGrid
作为一个PropertyGrid,我试图让它显示eventsTab(我无法用上面列出的任何方式显示)

如果我理解正确,您希望为自定义类的事件提供一种在VS IDE属性编辑器中显示的方式

只需对类进行一些更改,就可以相当简单地完成此操作。首先,您需要了解VS实际上编译表单以在IDE设计器中使用。具体来说,为了创建/绘制表单,需要编译
InitializeComponent
中的所有设计器代码

这意味着为了让类事件(和道具)在IDE中显示,类需要是
组件
(或
控件
),以便可以像IDE属性编辑器中的任何其他组件一样进行编译。它不能是运行时的类实例,因为表单编辑器未检查该代码

我已经使用过好几次这样的类,这些类在运行时充当普通类,但通过from设计器在IDE中添加了设置属性等功能(例如,具有
ExtenderProvider
功能的类)。对类的更改从以下内容开始:

class Validator:Component, ISupportInitialize
{
    // fake props
    public string Foo { get; set; }
    public int Bar  { get; set; }

    public event ValidatingEventHandler Validating;
    public delegate void ValidatingEventHandler(object sender, EventArgs e);

    public event ValidatedEventHandler Validated;
    public delegate void ValidatedEventHandler(object sender, EventArgs e);

    public Validator(string foo, int bar) 
    { 
    }
    public Validator()
    {
    }

    // ISupportInitialize methods
    public void BeginInit()
    { 
    }
    public void EndInit()
    {
    }
}
Form.Validator.Items<ValidationItems>
编译并在工具箱中提供验证程序。将其中一个拖到表单/组件托盘中。选择它,打开属性编辑器,然后查看IDE中显示的属性和事件:

验证程序组件属性()。事件视图:

双击所需的事件,VS将添加骨架事件处理程序供您编辑

组件的护理和喂食 只需让类从组件继承即可完成大部分工作。需要或可能会出现一些与组件相关的事情。其中大多数都是简单的问题和修复

简单导体 作为一个组件,验证器类必须有一个简单(无参数)的构造函数。VS不知道如何使用上面的
(字符串foo,int-bar)
版本来实例化它

如果您的代码依赖于这些参数来初始化构造函数中的其他内容,那么这可能会导致问题。答案是
isupportionalize

i支持初始化 此接口支持VS将从设计器代码调用的BeginInit和EndInit方法,因为它现在负责设置组件的属性:

// 
// validator1
// 
this.validator1.Bar = 0;
this.validator1.Foo = null;
this.validator1.Validating += new Validator.ValidatingEventHandler(this.validator1_Validating);
...
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.tableLayoutPanel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.validator1)).EndInit();
this.ResumeLayout(false);

...
private Validator validator1;          // note: no params
如您所见,设计器代码在设置完所有属性后所做的最后一件事是调用类/组件上的
EndInit
。任何使用
foo
bar
的初始化代码都可以简单地移动到那里

性质 类的属性和事件现在将显示在IDE中。如果要隐藏其中任何一项(可能只有在存在要验证的实际项目时才有意义),可以使用
Browsable
属性防止它们显示在属性窗格中:

[Browsable(false)]
public string Foo { get; set; }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int Bar  { get; set; }
为了确保VS确实序列化了希望通过IDE管理的对象,请使用
DesignerSerialization
属性:

[Browsable(false)]
public string Foo { get; set; }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int Bar  { get; set; }
对不希望VS序列化的任何属性使用
DesignerSerializationVisibility.Hidden

最后,OP提到了
验证器使用的“项目集合”。如果验证器上有集合类属性(例如
),则将显示该属性的默认集合编辑器。这可能是可取的,也可能不是可取的,这取决于项目是什么。您可以
[Browsable(false)]
将其隐藏

如果您确实希望通过IDE添加/编辑项目,那么还有更多的工作要做,但这是另一回事


补遗 这是关于新的,正在出现的,甚至是想要进入物品的欲望
private void validationItem1_Validating(object sender, EventArgs e)
{

}
private void validationItem1_Validating(object sender, EventArgs e)
...
private void validationItem1_Validating_1(object sender, EventArgs e)
...
private void validationItem1_Validating_2(object sender, EventArgs e)
private void validator1_ValidationComplete(object sender, 
                     ValidationCompleteEventArgs e) 
{
}