Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有没有办法访问子类';设计器生成的组件容器?_C#_Winforms_Inheritance_Windows Forms Designer_Devexpress Windows Ui - Fatal编程技术网

C# 有没有办法访问子类';设计器生成的组件容器?

C# 有没有办法访问子类';设计器生成的组件容器?,c#,winforms,inheritance,windows-forms-designer,devexpress-windows-ui,C#,Winforms,Inheritance,Windows Forms Designer,Devexpress Windows Ui,在Visual Studio中创建表单时,设计器会自动生成一个组件容器: /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; // ///必需的设计器变量。 /// private System.ComponentModel.IContainer components=null;

在Visual Studio中创建表单时,设计器会自动生成一个组件容器:

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
//
///必需的设计器变量。
/// 
private System.ComponentModel.IContainer components=null;
我们有几十个表单,所有这些表单都共享一个公共基类,以便于放入一些公共功能(“您有未保存的数据,是否确实要关闭此窗口?”等等)。每个表单都有自己的组件(它们有不同的菜单和按钮等等,所以没有人认为有必要让它们继承该组件)。现在我们已经意识到,我们希望向所有这些BarManager添加一个事件处理程序

我希望能做这样的事情:

public partial class Foo : Form
{
   ...
   private void Foo_Shown(object sender, EventArgs e)
   {
       this.components.Components.OfType<BarManager>().ToList().ForEach(tb =>
       {
           tb.SomeEvent += new EventHandler(FooHandler);
       });
   }

   protected void FooHandler(object sender, EventArgs e)
   {
       // do stuff
   }
   ...
}
公共部分类Foo:Form
{
...
显示私有void Foo_(对象发送方,事件参数e)
{
this.components.components.OfType().ToList().ForEach(tb=>
{
tb.SomeEvent+=新的事件处理程序(foodhandler);
});
}
受保护的void foodhandler(对象发送方、事件参数e)
{
//做事
}
...
}
如果它在
控件
集合中,那么这种方法可以很好地工作,但是由于
组件
是私有的,所以Foo及其控件有单独的集合


有没有办法在不修改每个子类的情况下实现这一点?我怀疑这可以通过反射来实现(我不太熟悉),但如果可能的话,我更喜欢不使用反射的解决方案。

由于设计器将
组件
变量生成为私有,反射是唯一的方法。当然,您可以很聪明,并且确保反射只用于获取实例一次,之后您将使用您的变量指向该实例,这样后续的访问将更加高效

您可以创建自己的设计器代码序列化程序,但我认为这有点过分了。另外,这不会使现有的表单组件更可用(除非您重新打开每个组件的设计器)

如果可以的话:既然每个表单只有一个工具栏(或者看起来是这样),为什么不递归地浏览表单的控件集合,直到找到它的实例

编辑:


由于您使用的是DexExpress,因此表单中会有
DevExpress.xtrabar.BarDockControl
实例作为控件放置在表单中。它们充当组件工具栏对象的容器。在运行时以
窗体.Controls
查找这些控件。他们有一个
Manager
属性,可以为您提供他们所连接的酒吧管理器。当然,从那里你可以访问它包含的每个工具栏。

我希望你知道,这不会给你可能在运行时动态创建的工具栏?@Crono-Yep,我们不会以这种方式创建任何工具栏,所以没关系;它们都是由设计师设计的。我刚刚意识到我过于简单化了;它们实际上是DevExpress BarManager对象,据我所知,它们不在控件集合中的任何位置。