1

在 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 及其控件具有单独的集合。

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

4

1 回答 1

1

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

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

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

编辑:

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

于 2014-02-20T19:37:13.763 回答