Use DELEGATE in C# to Communicate Between Controls

Yesterday I split one custom “ExpenseTimeGrid” control into two web controls “SelectFeeScheduel” (control 1) and “DisplayTimeGrid” (control 2).  How do I call a method in control 2, if a certain button was pressed in control 1.  Control 1 doesn’t know anything about methods in control 2 and can be used completely independently from control 2.

For these exact circumstances one can use delegates and events.  Here is the situation.  Two custom web controls are placed on a single ASPX page.  Second control is not yet visible.  It will become visible, when user clicks on Select button in first control.

  <ala:PickFeeSchedule runat="server"  />
  <ala:ExpenseEntryGrid runat="server"  Visible="false" />

Second control has a public method that will be called from outside world. It expects to receive certain parameters:

   public void Build_Time_Entry_Grig(object sender, FeeSchedEventArgs e)
   {
       // Populate key fields above Time Entry Grid
       ltrCustomer_ID.Text = e.Customer_ID.ToString();
       ltrCustomer_Name.Text = e.Customer_Name;
       ltrProject_ID.Text = e.Project_ID.ToString();
       ltrProject.Text = e.Project_Name;
       ltrService_Provider_ID.Text = e.Service_Provider_ID.ToString();
       ltrService_Provider.Text = e.Service_Provider_Name;
       ltrWeekRange.Text = ALA.TimeAndExpense.Utility.Shared.GetWeekRange(ltrOffset.Text);
       // ... and then call internal protected method
       Build_Time_Entry_Grig();
   }

Control 1 can’t call Build_Time_Entry_Grig() method directly, because it is not visible, not accessible and not defined there.  Instead we have to use this trick:  (1) We will create a class to carry required parameters, and (2) inside control 1 we will define a delegate to a method.

Look how Build_Time_Entry_Grig(object sender, FeeSchedEventArgs e) is defined. It has a regular sender parameter and unusual e of type FeeSchedEventArgs argument.  FeeSchedEventArgs is a class that we define to pass required parameters from one control to the other:

public class FeeSchedEventArgs : System.EventArgs
{
 public readonly int Customer_ID;
 public readonly string Customer_Name;
 public FeeSchedEventArgs(int custID, string custName)
 {
  Customer_ID = custID;
  Customer_Name = custName;
 }
}

Inside control 1 we need to define a delegate to the method:

   public delegate void DisplayTimeGrid(object sender, FeeSchedEventArgs e);

   public event DisplayTimeGrid Build_Time_Entry_Grid;

Also, we need to load required parameters and trigger the event somewhere in the code:

       FeeSchedEventArgs e = new FeeSchedEventArgs(_custID, _custName);
       Build_Time_Entry_Grid(this, e);

Looks like we are calling Build_Time_Entry_Grid() inside control 1, but we only know that return type (void) and parameter types. Now outside world can attach to this delegate any method that matches this return type and these parameters.

And the final step is to connect call from control 1 and method in control 2.  To do that we need just one line of code in ASPX.CS file:

protected void Page_Load(object sender, EventArgs e)
{
 pfsPickFeeSchedule.Build_Time_Entry_Grid +=
    new Control_PickFeeSchedule.DisplayTimeGrid(eegExpenseEntryGrid.Build_Time_Entry_Grig);
}

This (above) is an event handler syntax that links delegate DisplayTimeGrid on first control with actual method Build_Time_Entry_Grig() inside second control.

(Visited 582 times, 1 visits today)

1 Comment

Your question, correction or clarification Ваш вопрос, поправка или уточнение