Question

When you make a form in Visual Studio, the Designer automatically generates a components container:

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

We have a couple dozen forms, all of which share a common base class to make it easy to put in some common functionality ("You have unsaved data, are you sure you want to close this window?" and so on). Each form has its own BarManager component (they have different menus and buttons and so on, so nobody saw a need to have them inherit that component). Now we've realized that we'd like to add an event handler to all of those BarManagers.

I was hoping to be able to do something like this:

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

If it was in the Controls collection that approach would work just fine, but since components is private, Foo & its controls have separate collections.

Is there any way to accomplish this without modifying every single subclass? I suspect it can be done with reflection (which I'm not very familiar with), but I would prefer a solution without reflection if that's possible.

Était-ce utile?

La solution

Since the designer generates the components variable as private, reflection is the only way to go. Of course you can be clever and be sure that reflection will be used only once to fetch the instance that you will thereafter point to with a variable of yours, so that subsequent access will be more efficient.

You could make your own designer code serializer, but I think it's a bit of an overkill. Plus, that won't make existing forms components variable more available (unless you reopen the designer for each of them).

If I may: since every forms only have one toolbar (or so it seems?), why don't you browse the form's collection of controls recursively until you find an instance of it?

EDIT:

Since you're using DexExpress then your form will have DevExpress.XtraBars.BarDockControl instances placed as controls in the form. They are acting as the containers of your component toolbar objects. Look for those at runtime in Form.Controls. They have a Manager property that will give you the bar manager they're attached to. Of course from there you'll have access to every toolbars it contains.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top