问题
I've created a WinForms application that includes a custom component.
The component needs to fire one of it's events on start up but, at the time the component's constructor is called, all of the event handlers are still null.
What I need is an event that tells me the window owning the component has loaded and all the event handlers have been set.
However, it appears that components have no Load
event. In fact, it appears they don't come with any events at all with the sole exception of the Disposed
event.
How can my component know when it's save to fire off an event on start up?
回答1:
One possible solution, is to fire the event when the Component is wired to the listener. You need to create your own event property.
class MyClass
{
private static readonly _myEvent = new object();
private EventHandlerList _handlers = new EventHandlerList();
public event EventHandler MyEvent
{
add
{
_handlers.AddHandler(_myEvent, value);
OnMyEvent(); // fire the startup event
}
remove { _handlers.RemoveHandler(_myEvent, value); }
}
private void OnMyEvent()
{
EventHandler myEvent = _handlers[_myEvent] as EventHandler;
if (myEvent != null) myEvent(this, EventArgs.Empty);
}
...
}
回答2:
There are at least 2 different ways.
The first way is to keeping track of the container during design time using Site (Site is not called during runtime). It works just saving ContainerControl property during design time so during runtime it can be used.
You can see it in property browser of some components of the framework.
private ContainerControl _containerControl;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public ContainerControl ContainerControl
{
get { return _containerControl; }
set
{
_containerControl = value;
if (DesignMode || _containerControl == null)
return;
if (_containerControl is Form)
((Form) _containerControl).Load += (sender, args) => { Load(); };
else if (_containerControl is UserControl)
((UserControl)_containerControl).Load += (sender, args) => { Load(); };
else
System.Diagnostics.Debug.WriteLine("Unknown container type. Cannot setup initialization.");
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
public override ISite Site
{
get { return base.Site; }
set
{
base.Site = value;
if (value == null)
return;
IDesignerHost host = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
if (host == null)
return;
IComponent componentHost = host.RootComponent;
if (componentHost is ContainerControl)
ContainerControl = componentHost as ContainerControl;
}
}
private void Load()
{
}
The second method is to implement ISupportInitialize in the Component. In this case Visual Studio (2013) during design time generate the code that calls ISupportInitialize methods (BeginInit and EndInit) on the Component.
来源:https://stackoverflow.com/questions/17332643/determining-when-the-owner-of-a-component-has-loaded