有没有办法访问子类'Designer生成的组件容器?

时间:2014-02-20 19:29:56

标签: c# winforms inheritance windows-forms-designer devexpress-windows-ui

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

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

我们有几十种表单,所有表单共享一个公共基类,以便轻松放入一些常用功能(“您有未保存的数据,您确定要关闭此窗口吗?”等等) 。每个表单都有自己的BarManager组件(它们有不同的菜单和按钮等等,因此没有人认为需要让它们继承该组件)。现在我们已经意识到我们想要为所有BarManagers添加一个事件处理程序。

我希望能够做到这样的事情:

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
   }
   ...
}

如果它在Controls集合中,该方法可以正常工作,但由于components是私有的,Foo&amp;它的控件有单独的集合。

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

1 个答案:

答案 0 :(得分:1)

由于设计者将components变量生成为私有,因此反射是唯一的方法。当然,你可以很聪明,并确保只使用一次反射来获取你将使用你的变量指向的实例,这样后续访问将更有效。

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

如果我可以:因为每个表单只有一个工具栏(或者看起来好像?),为什么不递归地浏览表单的控件集合,直到找到它的实例?

修改

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