dinsdag, november 21, 2006

System.Web.UI.WebControls.WebControl doesn't fire all events

During the development of a ServerControl for a masterpage in a Sharepoint site, I added some eventhandlers in the CreateChildControls(): DayRender, VisibleMonthChanged and SelectionChanged.

After debugging, I noticed that only the DayRender event worked. I googled sites and newsgroups to find a solution, but I didn't find an answer....
After sending this problem to a colleague(thanks to: Sam), he answered this:

If you inherit controls from the WebControl class, you will get problems with events and state. So if you need dynamic controls, let them inherit from the CompositeControl class, this class is special made for controls that contains other controls.

At the CompositeControl MSDN page I found this:
The CompositeControl class is an abstract class that provides naming container and control designer functionality for custom controls that encompass child controls in their entirety or use the functionality (STATE AND EVENT HANDLING?!!?) of other controls.

Below some code of a custom Calendar that inherit from CompositeControl :

public class MailCalendar : System.Web.UI.WebControls.CompositeControl

{
private System.Web.UI.WebControls.Calendar ctlCalendar;

protected override void Render(HtmlTextWriter writer)
{
this.EnsureChildControls();
this.ctlCalendar.RenderControl(writer);
}

protected override void CreateChildControls()
{
this.Controls.Clear();
this.ctlCalendar = new System.Web.UI.WebControls.Calendar();
ctlCalendar.VisibleDate = DateTime.Today; this.ctlCalendar.DayRender _
+= new DayRenderEventHandler(ctlCalendar_DayRender);

this.ctlCalendar.VisibleMonthChanged _
+= new MonthChangedEventHandler(ctlCalendar_VisibleMonthChanged);

this.ctlCalendar.SelectionChanged _
+= new EventHandler(ctlCalendar_SelectionChanged); this.Controls.Add(ctlCalendar);
}

void ctlCalendar_SelectionChanged(object sender, EventArgs e)
{
this.Context.Response.Redirect(.......);
}

void ctlCalendar_VisibleMonthChanged(object sender, MonthChangedEventArgs e)
{
ctlCalendar.VisibleDate = e.NewDate;
}

void ctlCalendar_DayRender(object sender, DayRenderEventArgs e)
{
// Set date to bold if its today
Style boldStyle = new Style();
boldStyle.Font.Bold = true;

if (e.Day.Date == DateTime.Today)
{ e.Cell.ApplyStyle(boldStyle); }
}
}


More info: Webblog ScottGu

Geen opmerkingen: