用户控件(动态加载)

来源:互联网 发布:黑马程序员 网盘 编辑:程序博客网 时间:2024/05/01 16:35

所谓动态加载,就是一开始不把用户控件直接添加到.aspx页面上,而是根据需要从codebehind代码那里以编程方式添加。这样做的好处是可以针对不同的需要加载不同的用户控件。要注意的是,我这里说的加载的办法是用codebehind时要做的,如果只是用<script>块在aspx页面加代码来实现这个,可能方法会不同,具体可以参看.net framework sdk 文档,地址--点这里---。
下面来看codebehind的解决办法。 注意这里用的示例控件是第22篇文章“用户控件(添加事件)”里的那个。
加载用户控件是用LoadControl方法,
Control uclogin=LoadControl("xxx.ascx");
这一句就是把xxx.ascx文件里的用户控件取出来,返回的是Control类型
得到用户控件后,就可以把控件加到页面的某个容器控件里面
//声明一个容器
protected System.Web.UI.WebControls.PlaceHolder placelogin;
//把刚才的控件加到里面
placelogin.Controls.Add(uclogin);
PlaceHolder控件是一个专门用来乘放东西的控件,在页控件层次结构中为以编程方式添加的控件保留位置。
这样基本工作就完成了,但是……要做的还有很多。如果只是这样做的话,我们没有办法使用用户控件自定义的属性和事件。因为这里是加载了一个Control类型的控件。要使用我们自己的控件,需要做的就是把这个转换成自己的控件类型。从面向对象的角度来看,其实就是在同一个命名空间里做的两个类之间的操作。
private uc_event uclogin;
private void Page_Load(object sender, System.EventArgs e)
{
   uclogin=(uc_event)LoadControl("uc_event.ascx");
   placelogin.Controls.Add(uclogin);
   uclogin.boxBgColor="#000000";
}

上面的代码顺便加了一个设置属性的语句,现在这个语句可以起作用。值得一提的是,vs.net一般在这里会给出智能提示来让你选择需要的属性。
还记得我们的uc_event控件还有一个logiin事件吗?现在我们也可以使用这个事件,按照事件一般都放到 InitializeComponent()里面,我们也可以把这个事件放到那里,
private void InitializeComponent()
{
   this.Load += new System.EventHandler(this.Page_Load);
   this.uclogin.login+=new prac.uc_event.loginhandler(uclogin_login);
}

然后运行……出错了吧~~~这是因为asp.net的页面执行流程是 OnInit --> Page_Load , InitializeComponent()在OnInit里面,所以就先执行这个,可是在运行这个的时候还没有对uclogin进行具体的操作呢!解决的办法是把这个事件的订阅放到设置属性的后面
uclogin=(uc_event)LoadControl("uc_event.ascx");
placelogin.Controls.Add(uclogin);
uclogin.boxBgColor="#000000";
this.uclogin.login+=new prac.uc_event.loginhandler(uclogin_login);

这样就没有问题了。现在可以容易的根据条件进行不同控件的加载了。
private uc_event uclogin;
private userck uck;

private void Page_Load(object sender, System.EventArgs e)
{
   if(Session["login"]!=null)
   {
     if(Session["login"].ToString()=="red")
     {
       uclogin=(uc_event)LoadControl("uc_event.ascx");
       placelogin.Controls.Add(uclogin);
       uclogin.boxBgColor="#000000";
       this.uclogin.login+=new prac.uc_event.loginhandler(uclogin_login);
     }
   }
   else
   {
     uck=(userck)LoadControl("userck.ascx");
     placelogin.Controls.Add(uck);
   }
}

要注意的是,虽然是根据条件加载不一样的控件,可是声明的时候还是两个都做比较方便。
总的来说,加载用户控件的过程其实就是一个类在另一个类里面的引用,当然,这两个类都在同一命名空间里。因为这些都是在codebehind里面完成的,而且在声明控件实例的时候用的都是private级别的,所以也就不需要在.aspx页面上放什么东西了。
这是前面的.aspx页面的全部内容:
<%@ Page language="c#" Codebehind="uc_load.aspx.cs" AutoEventWireup="false" Inherits="prac.uc_load" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>uc_load</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<asp:PlaceHolder id="placelogin" runat="server"></asp:PlaceHolder>
</form>
</body>
</HTML>

我们的用户控件就添加在红色部分。

原创粉丝点击