今天在asp.net后台通过Page.LoadControl方法添加用户控件后,发现用户控件中的OnInit中的事件没有执行,我们先看看我的用户控件中涉及该问题的代码:
/// <summary >
/// SDDropDownList类型,控件可根据之类型自动初始化下拉项
/// </summary >
public _SourceType SourceType
{
get;
set;
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (!IsPostBack)
{
DataBind_LocalDDL(SourceType);
}
}
public void DataBind_LocalDDL(_SourceType _SourceType)
{
switch (_SourceType)
{
case _SourceType.Storage_Goods_Sort:
{
DDLDataBind(droplist, DictionaryBLL.GetModelList("DCID=002"));
break;
}
case _SourceType.Storage_Goods_GState:
{
DDLDataBind(droplist, DictionaryBLL.GetModelList("DCID=032"));
break;
}
……
}
private void DDLDataBind(System.Web.UI.WebControls.DropDownList DDL, List<SDERP.Model.SysManage.Sys_Dictionary > DataSource)
{
ListItem Item = new ListItem("--请选择--", "");
DDL.DataValueField = "DID";
DDL.DataTextField = "Dname";
DDL.DataSource = DataSource;
DDL.DataBind();
DDL.Items.Insert(0, Item);
}
再看看我调用页面中涉及该问题的代码:
protected override void Page_Load(object sender, EventArgs e)
{
base.Page_Load(sender, e);
InitSearchPanel();
}
protected virtual void InitSearchPanel()
{
……
IControls icontrols = (IControls)Page.LoadControl("~/Controls/SDDropDownList.ascx");
SDDropDownList iicontrol = icontrols as SDDropDownList;
if (icontrols != null)
{
SearchPanelID.Controls.Add(iicontrol);
if (!string.IsNullOrEmpty(dr["ControlSourceID"].ToString()))
{
iicontrol.SourceType = (Controls._SourceType)Enum.Parse(typeof(Controls._SourceType), dr["ControlSourceID"].ToString());
}
……
}
}
经检查后发现,问题出在SearchPanelID.Controls.Add(iicontrol)这行代码中,
在asp.net中,在后台动态添加的用户控件,其初始化工作是在用户控件被添加到页面上开始的,而不是在加载时开始。也就是说,我的用户控件在SearchPanelID.Controls.Add(iicontrol)这行代码后马上开始初始化工作,也就是执行用户控件的OnInit方法,而在此时,用户控件的SourceType属性并没有赋值,也就是值为None,所以用户控件的DataBind_LocalDDL事件中,就不能为droplist自动加添下拉项了。
改写代码,将
if (!string.IsNullOrEmpty(dr["ControlSourceID"].ToString()))
{
iicontrol.SourceType = (Controls._SourceType)Enum.Parse(typeof(Controls._SourceType), dr["ControlSourceID"].ToString());
}
这段代码移到 SearchPanelID.Controls.Add(iicontrol)之前,问题解决。也就是:
protected virtual void InitSearchPanel()
{
……
IControls icontrols = (IControls)Page.LoadControl("~/Controls/SDDropDownList.ascx");
SDDropDownList iicontrol = icontrols as SDDropDownList;
if (icontrols != null)
{
if (!string.IsNullOrEmpty(dr["ControlSourceID"].ToString()))
{
iicontrol.SourceType = (Controls._SourceType)Enum.Parse(typeof(Controls._SourceType), dr["ControlSourceID"].ToString());
}
SearchPanelID.Controls.Add(iicontrol);
……
}
}
总结:
1,
我们在asp.net后台中动态添加用户控件时,在Page.LoadControl("控件地址")加载控件的时候,用户控件未被初始化,只有当用户控件添加到页面元素中时,才会开始初始化.
2,我们在开发WebForm项目时,一定要清楚了解页面和控件的生命周期,才能在复杂的逻辑处理中做到不出错。