Why Is EventHandler in Controller Null?

Apr 1, 2009 at 3:46 PM
I have a page (master/page scenario) with multiple user controls on it.  One control contains a treeview that when selected needs to cause a refresh of a grid in another user control on the page.    When the user control containing the treeview has a node selection made, I raise an event in the view for the presenter to catch:

        protected void RadTreeView1_NodeClick(object sender, RadTreeNodeEventArgs e)
        {
            if (NodeSelectionChanged != null)
            {
                CommandEventArgs ev = new CommandEventArgs(e.Node.Value, null);
                NodeSelectionChanged(this, ev);
            }
        }

The presenter catches it correctly and calls a method in the controller to set a property and then raise another event that the presenter for the grid user control will respond to:

        public override void OnViewLoaded()
        {
            // Implement code that will be executed every time the view loads
            View.NodeSelectionChanged += new CommandEventHandler(View_NodeSelectionChanged);
        }

        void View_NodeSelectionChanged(object sender, CommandEventArgs e)
        {
            _controller.SetSelectedNode(Convert.ToInt32(e.CommandName));
        }

That controller code looks like this:

        public void SetSelectedNode(int iNodeId)
        {
            CurrentUser.SelectedNode = iNodeId;
            //now raise event that brochure grid will subscribe to
            if (NodeSelectionChanged != null)
            {
                CommandEventArgs ev = new CommandEventArgs(iNodeId.ToString(), null);
                NodeSelectionChanged(this, ev);
            }
        }

The code in the presenter for the grid that is listening for this NodeSelectionChanged event fired by the controller is:

        public override void OnViewLoaded()
        {
            // Implement code that will be executed every time the view loads
            _controller.NodeSelectionChanged += new CommandEventHandler(Controller_NodeSelectionChanged);
        }

        private void Controller_NodeSelectionChanged(object sender, CommandEventArgs e)
        {
            int iNodeId = Convert.ToInt32(e.CommandName);
            View.FillGrid(LBBrochure.GetByGroupId(iNodeId));
        }

My problem is that in the contoller code that is raising the event, the following line is null:

           if (NodeSelectionChanged != null)

Somehow my grid presenter is not attaching to the proper event handler so this is null?

Am I going about this wrong (bubbling events up to controller for others to attach to as needed)?

Thx!

 

Apr 1, 2009 at 7:46 PM
I figured it out.  My bad.

I was creating new controllers all over the place, instead of tying all my presenters on the page (for the user controls) to the same controller as the page itself.

Saw the error of my ways after looking over the MVPWithCWAP sample again :)
Developer
Apr 1, 2009 at 8:54 PM

Hi ksuvalk,

 

As you said, you are having problems with the controller instantiations.  By default presenters have in their constructor the controller parameter decorated with the [CreateNew] attribute.

This means that each time a presenter is created (in most scenarios on each request) a new controller instance is created and injected.

So the problem is that the grid presenter and the treeView presenter are listening to events in different instances of controller.

 

Solution: You should share the same instance of the controller between both presenters. To achieve that you might find useful the CreateShared Attribute from the WCSFContrib to inject the same controller instance in several presenters. Also, perhaps you may want to check the following discussion where Ezequiel Sculli explains how to use this attribute:

·         The "Composite" in CompositeWeb - on inter-presenter communications 

 

Let me know if you find this useful!

 

Matias Bonaventura

http://blogs.southworks.net/matiasb