Catching events

Cassio

Junior Contributor
Joined
Nov 30, 2002
Messages
276
Location
Rio de Janeiro
Hi!
C#: I have 2 projects in the solution. One contains a ASP.NET webform and the other contains a controler class. The controler project references the ASP.NET project, therefore the ASP.NET project cant reference the controler class.

How can I pass the webforms events to the controler class so it knows when a form event is fired?

Here's what did with no luck:

Code:
public class WebForm1 : System.Web.UI.Page
{
     protected System.Web.UI.WebControls.TextBox TextBox1;
     
     public delegate void FormLoad(object o, System.EventArgs e);
     public event FormLoad onFormLoad;
	
     public string texto
    {
	get
    {
	return TextBox1.Text;
    }
	set
    {
	TextBox1.Text = value;
    }
}

private void Page_Load(object sender, System.EventArgs e)
     {
	onFormLoad(sender, e);			
     }

}

And in the controler class:
Code:
public class Controler
{
	pagina.WebForm1 f = new pagina.WebForm1();
	public Controler()
            {
		f.onFormLoad += new pagina.WebForm1.FormLoad(f_onFormLoad);
	}

	private void f_onFormLoad(object o, System.EventArgs e)
	{
		f.texto = "Great!!";
	}
}

Now, obviously the contructor of the controler will never be called since its never instanciated. And I cant instanciate it cause the webform project isnt aware of the controler class.

How can I go around it?

Thanks!!!
 
Last edited:
Before we look into your problem. . .

First why are you doing this:
Cassio said:
Code:
public class WebForm1 : System.Web.UI.Page
{
. . .
public delegate void FormLoad(object o, System.EventArgs e);
public event FormLoad onFormLoad;
. . .
instead of just:
Code:
public class WebForm1 : System.Web.UI.Page
{
. . .
public event System.EventHandler onFormLoad;
. . .

the only diference between FormLoad and System.EventHandler is yours is intrinsic to your class

next. . .

What purpose does your OnFormLoad event serve that cant be handled in the inherited Load event already defined in UI.Page? I mean get rid of your Page_Load method as well as the OnFormLoad event, while in the constructor of the controller do:

Code:
public Controller()
{
f.Load += System.EventHandler(f_onFormLoad);
}


now. . . this doesnt help your situation in that you never instance the controller. . . so that begs the question, what is the purpose of the controller???
 
Yeah, I know im way out. I just thought it would be nice to have the webform encapsulated, so the controler layer would only see its public properties.
The problem is that I would have to reference the webform layer in the controler layer, and the webform layer wont reference the controler layer, so it can never be used sinse the starting point is always a webform, right?
 
Cassio said:
Yeah, I know im way out. I just thought it would be nice to have the webform encapsulated, so the controler layer would only see its public properties.
The problem is that I would have to reference the webform layer in the controler layer, and the webform layer wont reference the controler layer, so it can never be used sinse the starting point is always a webform, right?

Well, I think this will work:

nb: no guarantee that this code compiles or is syntactically correct or even that it will work. This code just outlines the approach I would take for solving this problem. . .

For your controller, derive from HTTPApplication, call it CustomHTTPApplication and save this in the utility project with the following definition:

PHP:
public class CustomHTTPApplication: HTTPApplication
{
   public void RegisterPage(System.Web.UI.Page aPage)
   {
	  aPage.Load += new EventHandler(PageLoad);
   }
 
   protected virtual void PageLoad(object o, System.EventArgs e)
   {
// Leave this empty
   }
}

With me so far??? :)

ok, now, in your web application Make a reference to the Utility Project and perform the following tasks
  1. change the code in your Global.cs file so that the global object derives from your class and not the HTTP Application
  2. Override the PageLoad Event for the application instance to perform the application specific task
  3. this is a neat thing I do in all my Global classes. define a static Method on global to return the actual Global Object so you dont have to cast the Page.Context.ApplicationInstance to global
PHP:
 public class Global : CustomHTTPApplication 
{
  protected override void PageLoad(object o, System.EventArgs e)  
  { 
	// Lets say you have three Page Classes in the Application Name Space
	// Page1, Page2, Page3
 
	if (o is Page1) 
	// Do Page1 Code here
 
	if (o is Page2) 
	// Do Page2 Code here
 
	if (o is Page3) 
	// Do Page3 Code here
 
   }
 
  public static Global Controller
  {
	get
	{
	  return (Global) HttpContext.Current.ApplicationInstance;
	}
  }
}

Haven't lost you yet have I? Hold on almost done. . . :)

Finally, override the void OnInit method in every controlled page:
PHP:
public class WebForm1 : System.Web.UI.Page
{
  protected override void OnInit(EventArgs e)
  {
	Global.Controller.RegisterPage(this);
  }
}

I don't see any reason why that won't do what you want. . .
Now, if you dont want to redefine the Web App's Global.PageLoad you could actually put code in the CustomHTTPApplication's Virtual PageLoad Method, you could also make a RegisterDelegate method on the CustomHTTPApplication and do some neat things like pass a third projects Class Method into the controller and in the RegisterPage assign that for the Load Event.

I hope I was some help here. Keep me posted as to how this works and good luck!
 
Back
Top