Friday, August 28, 2009

ASP.NET MasterPages and User Defined Events

ASP.NET MasterPages and User Defined Events

Master pages were introduced in ASP.NET 2.0 and are a great way to create a consistent layout for the pages throughout your application. I thought a good article would be to demonstrate how to create a custom event that web content pages can raise if they click on web server controls located in the master page. If you want to raise an event and pass data to an event handler, you need to create a class that inherits from System.EventArgs . EventsArgs is the base class for classes containing event data. It contains no event data. It is used by events to pass data to an event handler when an event is raised.

To begin with open Visual Studio 2008 and choose File > New > Web > ASP.NET Web Application. Add a master page to the project and name it Site.Master. Before going any further add a new class to the project and name it CustomArgs. Add the following code to the newly created class:
C#

   1:  public class CustomArgs : EventArgs

   2:  {

   3:  public bool Cancel { get; set; }

   4:        public string Message { get; set; }

   5:        public string NavigateTo { get; set; }

   6:  }



In the code above, CustomArgs inherits EventArgs. This means that when we raise an event in the master page, a reference to CustomArgs will be passed to our event handler, so we can set these properties and have the master page determine what to do next.
Go back to the master page and add the following code to create a new event:
C#

   1:  public EventHandler ButtonClick;



We have just created a new event called ButtonClick that accepts CustomArgs as the argument. Now add a Button to the page and add the following code to the Button’s Click event:
C#
---------------------

   1:  protected void Button1_Click(object sender, EventArgs e)

   2:  {

   3:  lblValue.Text = null;

   4:        if (ButtonClick != null)

   5:        {

   6:              CustomArgs args = new CustomArgs();

   7:              ButtonClick(sender, args);

   8:              if (args.Cancel)

   9:              {

  10:                    lblValue.Text = args.Message;

  11:  }

  12:              else

  13:              {

  14:                    Response.Redirect(args.NavigateTo);

  15:              }

  16:  }            

  17:  }



What’s happening in the code above is when a user clicks on the Button, which resides in the master page, it will check to see if there’s code that raises the ButtonClick event. If there is, the event handler will be executed. Once the event handler has completed, the master page will check the value of CustomArgs.Cancel property, and if it is false, it will display what is in the CustomArgs.Message property; otherwise it will navigate to the CustomArgs.NavigateTo page.
To see this in action add two web content forms to the project and select the master page added earlier. Leave these pages as WebForm1.aspx and WebForm2.aspx:



To be able to call the event from the master page, you’ll need to add a new MasterType directive to the both pages:


   1:  <%@ MasterType VirtualPath="~/Site.Master" %>



This provides a way to create a strongly typed reference to the master page when the master page is accessed from the Master() property. Now we must create an event handler for the ButtonClick event. Add the following code to WebForm1.aspx:
C#
-----------------------------


   1:  protected void Page_Load(object sender, EventArgs e)

   2:  {

   3:       Master.ButtonClick += new EventHandler<CustomArgs>(MasterButtonClick);

   4:  }

   5:   

   6:  private void MasterButtonClick(object sender, CustomArgs e)

   7:  {

   8:  if (!string.IsNullOrEmpty(TextBox1.Text))

   9:        {

  10:              e.Cancel = false;

  11:              e.NavigateTo = "~/WebForm2.aspx";

  12:  }

  13:        else

  14:        {

  15:              e.Cancel = true;

  16:              e.Message = "There was no text entered...";

  17:  }            

  18:  }

  19:   



In the code above an event handler called MasterButtonClick has been created. This event handler will be raised when the user clicks the Button in the master page. To simulate a business application I’ve added a TextBox to the page so if the user leaves it blank, validation will fail and they should be alerted to this. This is made possible by setting the CustomArgs.Cancel property. If the user does enter data then they will be allowed to navigate to the next page.
Open the WebForm2.aspx page and add the following code to the code behind:
C#
---------------------------------

   1:  protected void Page_Load(object sender, EventArgs e)

   2:  {

   3:  Master.ButtonClick = delegate(object s, CustomArgs c)

   4:        {

   5:              c.Cancel = false;

   6:              c.NavigateTo = "~/WebForm1.aspx";

   7:  };

   8:  }



In the code above I have created an anonymous method that handles the ButtonClick event. This page will not validate anything and therefore will direct the user back to the WebForm1.aspx page.

If you run the application and step through the code you’ll see that when you click on the button in the master page, it will check and execute the event handlers in the web content forms. This is a nice way of being able to create a wizard style application, but having the flexibility of raising events in the child pages when you need to.

No comments: