views:

111

answers:

2

I have my own custom control derived from System.Windows.Forms.TreeView which is present on the designer toolbox.

I add an instance of this custom control to my form (using the designer).

The purpose I created an inherited control is that I want to let the control itself handle its events since it's supposed to act as a View in a standard MVC design. I.e. when the node selection in the treeview changes I want the view to handle all interactions with the Model.

The problem is that when I add an event for my custom control (using the designer), the event gets added to my MainForm class. The only option in such case is to forward every event into my custom control, which doesn't feel very optimal.

Is there a way to control which class the event gets added to? I know it's technically possible since I can edit the auto-generated code for my MainForm and make the event being triggered into the custom control. That's clearly not the proper solution though.

Thanks.

+2  A: 

why don't you just override some of the methods in your derived class, e.g.:

protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
    {
    }
Tom Frey
That seems to be a good way of doing it, thanks. I guess I'll set this as the answer if it turns out to be impossible using the designer.
sharkin
Don't forget base. OnNodeMouseClick(e)
recursive
@recursive: Like magic it appeared on its own courtesy of intellisense :).
sharkin
+1  A: 

Tom Frey is right. If you want the behavior on a certain event to be handled by the class that would normally fire the event, the preferred technique is to override the appropriate method that fires the event to perform your task. The eventing infrastructure is overkill and not really designed for what you're trying to do here.

The reason is that you want every instance of your view to perform these actions. You don't want these actions to be dynamically assigned and determined at runtime by things external to your view (which is what events are for).

One important thing to include when you perform such an override, however, is the call to the base's implementation. If you don't, you may encounter strange errors:

protected override void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
{
    // Do stuff you want done before here
    base.OnNodeMouseClick(e);
    // Do stuff you want done after here
}

Calling the base class will fire the event and may perform other actions besides. If you want something done before the event fires and any external subscribers do their thing, put it before the call to the base. If you want something done after all the events have fired and been handled, put it after. Contrived example: if your control handled some data binding, then you might want to verify the databinding exists before the call to base and you might want to verify it's valid after (in case a handler munged something).

From MSDN:

The OnNodeMouseClick method also allows derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class.

Notes to Inheritors:

When overriding OnNodeMouseClick in a derived class, be sure to call the base class's OnNodeMouseClick method so that registered delegates receive the event.

Greg D
Thanks! Would you perhaps please clarify what kind of tasks would fit to perform prior to and after the call to the baseclass?
sharkin
Calling the base class will fire the event and may perform other actions besides. If you want something done before the event fires and any external subscribers do their thing, put it before the call to the base. If you want something done after all the events have fired and been handled, put it after. Contrived example: if your control handled some data binding, then you might want to verify the databinding exists before the call to base and you might want to verify it's valid after (in case a handler munged something).
Greg D