discover control events?

Tom Knowlton
Tom Knowlton used Ask the Experts™
on
At runtime, is it possible to discover programmatically which events are exposed by a user control (.ascx) and subscribe to them in some generic fashion?

What I am wanting to accomplish is to read in settings from a "layout" file which tells me which .ascx controls to load into memory (and display on the form).  I can get that to work, but then I don't know how to subscribe to the events of these controls, since I am dealing with them as a collection of generic "controls" vs a collection of different control types.

So the process would be something like this:

-read in the file
-run "LoadControl" for each control name listed in the file
-subscribe to any public events the control emits
-provide some sort of central processing for the events (yet to be determined).


Is this making any sense?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;

namespace Campus_Webstore
{
    public partial class SiteManager : System.Web.UI.Page
    {
        protected void Page_PreInit(object sender, System.EventArgs e)
        {
            this.MasterPageFile = "~/contentfiles/" + Page.StyleSheetTheme + "/TCSSite.Master";
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                GlobalMethods.InitControlList();
            }

            string layout = "";

            if (Request.QueryString["layout"] != null)
            {
                layout = Request.QueryString["layout"] as string;
            }
            else
            {
                layout = "default";
            }

            DisplayLayout(layout);
        }

        private void DisplayLayout(string layout)
        {
            GlobalMethods.divlayoutgencontrols.Clear();

            StreamReader sr = new StreamReader(Server.MapPath("~/CustomLayouts/") + Page.StyleSheetTheme + "/" + layout + ".xml");
            string filecontents = sr.ReadToEnd();
            string countstr = GlobalMethods.ExtractValueFromXML(filecontents, "<count>");
            int count = Convert.ToInt32(countstr);
            string tempGUID = "";
            string settings = "";
            string[] settingsarray = new string[count];

            for (int i = 1; i <= count; i++)
            {
                settings = GlobalMethods.ExtractValueFromXML(filecontents, "<" + i.ToString() + ">");
                settingsarray = settings.Split(',');

                Control c = LoadControl("~/UserControls/" + settingsarray[0] + ".ascx");
                c.Visible = true;
                tempGUID = Guid.NewGuid().ToString();
                c.ID = settingsarray[0] + tempGUID + i.ToString();

                GlobalMethods.divlayoutgencontrols.Add(c);
            }

            foreach (Control c in GlobalMethods.divlayoutgencontrols)
            {
                sitemanagercontrolsdiv.Controls.Add(c);
            }


            Master.CalcCartTotal();
            Master.ShowCat();
            Master.DisplayUser();

        }       
    }
}

Open in new window




the layout file:

<count>3</count>
<1>Countries</1>
<2>AddOrEditUser</2>
<3>ShoppingCart</3>

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Hi! I guess you can do it using reflection. Look following article:
http://msdn.microsoft.com/en-us/library/ms228976.aspx
You should load ascx with loadcontrol, then use GetEvents() methods:
Control control = LoadControl(controlname);
Type controlType = control.GetType();
BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public;  
ventInfo[] myEvents = controlType.GetEvents(myBindingFlags);
Tom KnowltonWeb developer

Author

Commented:
Okay, I can see the events for the control now:

EventInfo[] myEvents = controlType.GetEvents(myBindingFlags);

in my watch window I can see:

UserClickedOnNameAvailability
ChangePasswordWasClicked
etc.
etc.

 events emitted

Now -- how do I "hook up one of these events to an EXISTING METHOD already in my code behind...like so:


{Campus_Webstore.UserControls.NameAvailWasClicked NameAvailabilityEvent}

which is

myEvents[1]


something like...myEvents[1] += new Campus_Webstore.UserControls.NameAvailWasClicked(create_new_user_NameAvailabilityEvent);


or some such????

 void create_new_user_NameAvailabilityEvent(bool wasavailable)
    {
        create_new_user.ShowRotatingArrow(true);

        if (wasavailable)
        {            
            LabelResultMessage.Text = "That username is available.";
            ButtonClosePanelMessage.Visible = true;
            PanelMessage.Visible = true;
        }
        else
        {
            LabelResultMessage.Text = "That username is already taken.";
            ButtonClosePanelMessage.Visible = true;
            PanelMessage.Visible = true;

        }

        create_new_user.ShowRotatingArrow(false);
    }
Tom KnowltonWeb developer

Author

Commented:
Of course -- I won't know the name of the method to attach to in advance...I just know the signature of the event handler will match the delegate refereence inside the myEvents collection.
Tom KnowltonWeb developer

Author

Commented:
thx

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial