Har du nogensinde forsøgt at få 2 eller flere UserControls til at “tale” med hinanden i WebForms frameworket ?
En UserControl skal bruge en side som “host”, og på den måde kan vi få siden til at være en slags event-proxy, og styre de events der bliver kastet af de enkelte UserControls.
Du skal bruge 2 UserControls (.ascx) og en 1 WebForm (.aspx).
Tilføj en PlaceHolder til din aspx side, dernæst de ønskede kontroller i dine .ascx filer. Jeg har brugt en CheckBox kontrol i den ene UserControl og en DropDownList i den anden. Nu er meningen, at når jeg vinger CheckBoxen af, så skal min DropDownList populeres med navne. Jeg lader min aspx side styre hvordan dette bliver gjort.
Tilføj dette til din aspx fil:
<%@ Register Src="~/User1.ascx" TagName="uc1" TagPrefix="DMF" %>
<%@ Register Src="~/User2.ascx" TagName="uc2" TagPrefix="DMF" %>
Dernæst skal du tilføje noget kode i din .aspx fils code-behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
private User2 ctrl2;
protected void Page_Load(object sender, EventArgs e)
{
//load first and second UC
User1 ctrl = (User1)LoadControl("User1.ascx");
ctrl2 = (User2)LoadControl("User2.ascx");
//adding the UC's
phControls.Controls.Add(ctrl);
phControls.Controls.Add(ctrl2);
//find checkbox from first UC
CheckBox cbCheck = (CheckBox)FindControl("cbCheck", ctrl);
if (cbCheck != null) {
//add event handler for the first UC
cbCheck.CheckedChanged += new EventHandler(cbCheck_CheckedChanged);
}
}
protected void cbCheck_CheckedChanged(object sender, EventArgs e)
{
//find dropdown in second UC
DropDownList ddlNames = (DropDownList)FindControl("ddlNames", ctrl2);
if (ddlNames != null) {
//add item(s) to the dropdown in the second UC
ddlNames.Items.Add(new ListItem() { Text = "daniel", Value = "1" });
}
}
/// <summary>
/// Recursive FindControl
/// </summary>
/// <param name="controlName"></param>
/// <param name="control"></param>
/// <returns></returns>
private Control FindControl(String controlName, Control control)
{
if (control.HasControls())
{
foreach (Control item in control.Controls)
{
if (item.ID == controlName)
{
return item;
}
FindControl(item.ID, item);
}
}
return null;
}
}
På den måde kan du lade dine UserControls blive “styret” fra en reel side. Det kan der være fordele ved, men man skal også være en smule forsigtig med ikke at forurene ens aspx sider med logik der rent faktisk bør være i selve UserControlen.
Du kan downloade koden til eksemplet her.