动态加载用户控件的组件

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情
让我们来做个页面模版吧!有了模版是不是就可以统一了呢! Sure
比如:模版页 Template.ascx 中我们留出中间一个部分,或者你想要留出的一个空间,让以后放入你想要的内容。
好了!那么在我们的页面 index.aspx 上我们就可以引用这个 Template.ascx, 然后在空出的部分放入我们特别的东西,当然最好是在空的地方我们插入另外一个页面如: List.ascx
当然我们在做个页面 MyArchive.aspx. 同样的我们引用这个 Template.ascx, 然后再在空出大那个地方我们插入了另外一个页面 Archive.ascx.
非常好。我们要的两个 index.aspx. MyArchive.aspx 页面是不是一样的呢?就只有我们留空的那一个地方不一样而已。
当然这样的应用可以是各种各样,可以不用框架集而达到更完美的效果。而你的页面完全可以没有重复的东西。因为我们的页面完全是组装而成的!
那么有了这个美妙的想法之后我们就开始去实现。
 
技术点: 1 、怎么留出一个空间出来,然后还要让引用页找到这个空间。
        2 、怎么引用模版而且还要找出留出的空间。
        3 、怎么引用另外一页插入我们在模版页中留出的空间。
 
其实所有这些就需要用到三个组件,一个是用来保留的空间,一个是用来引用页面放入到我们保留出来的空间,这两个组件其实只是起到标记的作用而已。另一个也是主要的一个就是引用模版,然后处理引用页面并插入到模版中去。
 
1 、我们来解决的一个技术问题,留个空间很容易的就是 PlaceHolder 那么我们还要考虑到 ID 的问题 , 因为我们还要找到这个地方,当然我们可能要留几个不同的地方,这样就很有必要处理一下 ID 的问题。那么扩展 PlaceHolder 同时继承 INamingContainer
我们取名为: PlugArea
那么这个主要做的事情有两件事,把本身保存起来,然后在第三个组件用到的时候取出来。
public class PlugArea : PlaceHolder, INamingContainer {       
       public override string ID {
           get {
              return base.ID;
           }
           set {
              base.ID = value;
              AddToContext();
           }
       }
       private static readonly String contextKey = "Region.MasterPages.Region";
       private void AddToContext() {
           if ( HttpContext.Current != null ) {
              String myKey = contextKey + this.ID;
              if ( HttpContext.Current.Items.Contains(myKey) ) {
                  throw new InvalidOperationException(" 这个 ID'" + this.ID + "' 已经用了啦! ." );
              } else {
                  HttpContext.Current.Items[myKey] = this;
              }
           }
       }
       internal static PlugArea FindPlugArea( String ID ) {
           if ( HttpContext.Current == null ) {
              return null;
           }
           return HttpContext.Current.Items[contextKey + ID] as PlugArea;
       }  
    }
 
那么我们的 Template.ascx 可以写成这样
< %@ Control %>
< %@ Register TagPrefix="Region" Namespace="Region.Controls" Assembly="Region.Controls" %>
< HTML >
    <HEAD>    
       <title> 信息管理系统 </ title >       
    </HEAD>
    <bodyleftmargin="0"topmargin="0"marginwidth="0"marginheight="0">       <formrunat="server"id="Form1">      
       <tablewidth = 800align=center border=0cellpadding=0cellspacing=0><tr><td>     
       相同的第一部分
       </td></tr><tr><td>      
       <Region:PlugAreaid="part1"runat="server"/>     </td></tr><tr><td>
        相同的第二部分
        </td></tr><tr><td>
       <Region:PlugAreaid="part2"runat="server"/>
       </td></tr><tr><td>
       相同的第三部分
       </td></tr></table>
       </form>
    </body>
</ HTML >
 
2 、引用模版页的时候,在里面标记以下我们保留的空间应该插入哪个页面,标记以下就可以了!具体的事情由引用模版页的组建来搞定。继承 PlaceHolder
组建起名: SignArea
两件事情:一、只需把 ID 设成我们要插入那个空间组件的 ID.
          二、在后面把这个插入我们留出的空间的时候,把组建的路径设成一样的,避免路径不一样引起异常发生。
当然,我们要在这个 SignArea 内应用我们的页面。
public class SignArea : PlaceHolder {
      internal string Directory;
       public override string TemplateSourceDirectory {
           get {
              return Directory;
           }
       }
    }
 
我们可以这样用:
< Region: SignArea id = " part1"runat="server">
    这里可以用我前面的文章讲 LoadSky 来来引用用户页面,或直接写内容放这里。
</ Region: SignArea >
< Region: SignArea id = " part2"runat="server">
    同上第一部分。
</ Region: SignArea >
 
3 、应用我们的模版页并处理其中的模块插入。
继承 PlaceHolder
命名: LoadTemplate
做事情:一、重载 AddParsedSubObject 事件,在记录 PlaceHolder 中的 SignArea
二、加载 Template 页。
        三、根据 SignArea id 找到 PlugArea (用 PlugArea 内的 FindPlugArea ,也就是为什么要用静态方法的原因 ),然后把 SignArea 插入到 PlugArea 中去。
这三件事做完事情也就做完了
看一下代码:
public class LoadTemplate : PlaceHolder {    
        private ArrayList signarealist = new ArrayList();
        protected override void AddParsedSubObject(object obj)
        {
            if (obj is SignArea) {
              signarealist.Add(obj);
           }         
       }       
       protected override void OnInit(EventArgs e) {
           this.GetTemplate();
           base.OnInit(e);
       }
       private void GetTemplate() {
           if (TemplateFilePath == null) {
              throw new Exception("ûÓÐÄ£°åÒ³£¡");
           }
           Controls.Add(Page.LoadControl(TemplateFilePath));
           SignAreaInsertIntoPlugArea();
       }
       private void SignAreaInsertIntoPlugArea() {
           foreach (SignArea signarea in signarealist) {
              PlugArea plugarea = PlugArea.FindPlugArea(signarea.ID);
              if (plugarea == null ) {
                  throw new Exception("ÕÒ²»µ½²åÈëµÄ¿Õ¼ä'" + signarea.ID + "'");
              }
              SignArea.Directory = TemplateSourceDirectory;
              plugarea.Controls.Clear();
              plugarea.Controls.Add(signarea);
           }
       }
       public string TemplateFilePath{
           get {
              return (string)ViewState["TemplateFilePath"];
           }
           set {
              ViewState["TemplateFilePath"] = value;
              ChildControlsCreated = false;
           }
       }
    }
 
 
好我们来看看怎样引用模版页! index.aspx 页面:
< %@ Page %>
< %@ Register TagPrefix="Region" Namespace="Region.Controls" Assembly="Region.Controls" %>
< Region: LoadTemplate runat = "server"id="LoadTemplate "TemplateFilePath ="~/Template.ascx"> 
    <Region: SignArea id = "part1"runat="server">
    <Region: LoadSky id = "Sky1" skinPath="~/List.ascx "runat="server"/>
</ Region: SignArea >   
< Region: SignArea id = "part2"runat="server">
    <Region: LoadSky id = "Sky2" skinPath="~/ MyArchive .ascx "runat="server"/>
</ Region: SignArea >
</ Region:LoadTemplate >
 
那么运行一下完整的一个页面就出现在我们面前了。当然可以这样生成所有想要的一样风格的页面。
 
从一开始写到现在,最后这里就变成了传说中的那个 Masterpages 的技术。
就如同天下武学都源自少林一样
但是怎样灵活的在项目中运用呢?怎样做到面向组件的开发呢?就像是积木式开发,我们的叶面可以有不同的组件来完成,而整个叶面就是一个容器,我们只不过是往容器里添加不同的元素而已,因此只要我们的元素能够做到通用,一般化,那么元素积累到了一定的程度,元素足够的丰富就可以经而一举构造出我们想要得叶面。
更多地运用到下一篇文章再详细到来。下面我们先来看看怎么样加载组合我们的用户组件:
1 、让我们来先做两个元素,这里我就把用户组件 ascx 的文件称之为元素了。 Head.ascx Footer.ascx.
 
2、作个aspx叶面来加载着两个元素。
3、运行的效果如下:
 
哈哈!是不是很激动人心呢?
 
好让我们来动态加载,让头脚换一下位置怎么样!我们在aspx叶面上加一个按钮,在按钮的相应事件里改变加载不同的用户组件。事件的代码这样写:
运行之后:
赶快按下鼠标试试看
哈啊!是不是头脚换了位置了呢?
 
好!动态加载用户组件搞定。可以 Release 一下了。
 
那么这只是一个简单的应用,让我们期待下一篇文章再来领略动态加载组建的真正的应用。
坐着沙发等吧...
 
未完(持续)
    页面是用来浏览信息的!但是更重要的是和用户交互,根据不同的需求提供不同的内容服务,这是一种服务或是一种更贴近用户的人性化。(又在胡言乱语了! ^_^
动态加载叶面,根据不同的用户权限加载不懂的内容服务。根据用户的相应加载相应的内容服务。
还有另外一个应用就是做到页面与代码的分离。在 vs2003 里,一般 ascx aspx 文件,在刚建立的时候都直接跟一个 cs 文件关联。那么我们在写程序的时候就不能分开来做。作叶面和写后台代码的不能分开。为了能够做到作业面与作后台代码的能完全分开来,我们可以把后台的所有代码当作一个组件来做就可以了!这样一个不用跟 cs 文件关联的 aspx 叶面文件直接引用一个组件就可以了!那么组件可以加载不同的 ascx 文件最后组成一个完整的叶面。就这样一个项目的开发就像个机车制造厂一样组装不同的零件就有辆车出来了。软件也可以拿来组装,零件我们也可以订制,最后整体就可以出来了!(常常看别人的文章的时候怎么就觉得废话那么多,原来发现我废话也不少! ^_^
好!让我们step by step ,就从不需要关联cs文件的aspx叶面开始吧!(在vs2005里,我新建aspx叶面的时候就直接没有cs文件关联。但是直接有个不完整类型隐藏起来了。怎么用基类就成为问题了!隐藏部分应该是继承了Page了!那么根据单继承的原则我们是不能在继承别的类型的了。这个问题有待研究。)
根据aspx叶面运行原理。叶面要跟服务端交互必须通过一个run at server的form标签才能行得通。因此我不要先来写个form组件,那么form就应该是个容器的形势来承载叶面所有要与服务端交互的元素,(容器太重要了,namespace也可以看作容器,只不过是不能放东西而已,是虚拟的容器)
1、做form容器组建:继承继承他就行了,注意一点就是唯一ID的问题。自己继承的可能该改变了ID,那么回传的时候就找不到了啊。切记!当然render叶面的时候是通过遍历所有form容器内所有的组件来一个个render出来。所以要改 UniqueID。
示例一下:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
 
namespace Region.Controls {
   
    public class MyForm : System.Web.UI.HtmlControls.HtmlForm {
 
            public override string UniqueID {
            get {
                if (this.NoNameContainer && this.NamingContainer != this.Page ) {
                    return base.UniqueID.Substring(base.UniqueID.LastIndexOf(":")+1);
                } else {
                    return base.UniqueID;
                }
            }
        }
 
        protected override void RenderAttributes(HtmlTextWriter writer) {
            this. NoNameContainer = true;
            base.RenderAttributes (writer);
            this. NoNameContainer = false;
        }
       
        protected override void RenderChildren(HtmlTextWriter writer) {
            this. NoNameContainer = true;
            base.RenderChildren (writer);
            this. NoNameContainer = false;
        }
 
        private Boolean NoNameContainer = false;
    }
}
 

 
 
未完(持续)

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=78758
[ 点击此处收藏本文]   发表于 2004年08月19日 10:03 AM
href="http://blog.csdn.net/xinyulou/Services/Pingback.aspx" rel="pingback" />


 
空心菜 发表于2004-08-22 6:26 PM  IP: 220.173.7.*
不知所云

 
Region 发表于2004-09-07 10:09 PM  IP:
TrackBack来自 《动态加载用户控件的组件!(终结MasterPages技术)》

Ping Back来自:blog.csdn.net

 
开拓者 发表于2004-09-23 10:06 AM  IP: 61.144.226.*
请作者认真一点好吗?!看看你的东西!

 
region 发表于2004-09-25 11:08 AM  IP: 222.94.39.*
我也不知道是为什么?
我用word写的!放到这里就成这个样子了,也是没有办法

 
遇見鵬 发表于2004-09-29 3:35 PM  IP: 218.87.234.*
就是就是

 
ithanku 发表于2005-01-08 4:15 PM  IP: 221.219.56.*
先拷贝到UltraEdit 或 EditPlus,再拷贝到页面上,应该显示效果会好一些。:)
 (实在很懒,关于动态加载用户控件的内容实在写也写不完,说也说不完。关系到asp.net的一切!)
       我们要做没有关联cs文件的aspx叶面。其实叶面的东西并不在aspx上,而是在ascx上。Aspx所起的作用只是一个入口。对组件的引用而已,而组件就可以管理很多的ascx页面,所谓的叶面ascx叶面也应该是没有关联cs的叶面。
       所以整个系统所有的东西都是在组件里面,aspx是单纯的访问入口,ascx是纯页面的东西。Aspx入口调用组件,组件调用ascx页面以及相应客户的交互。
       只有这样才能做到每工与后台的很好的分开。
       完全可以有一个团队来开发页面(纯页面不需要任何的cs代码,全都是ascx),而有另一个团队来开发组件。最后组装成整个系统,由aspx调用组件就可以了。
       让我们来作个无代码关联的ascx叶面,叶面上有个按钮,然后写个组件加载这个ascx叶面,以及如何响应这个按钮的事件!
       (废话一下,写文章有时候不废话真是很痛苦的一件事情啊!)ascx叶面与处理叶面的后台代码分开是一件非常好的事情,不知你有没有发现一个叶面有只能与一个后台代码文件关联,不可能有两个类来关联这个叶面。而用组件来加载ascx以及相应事件,那么你就可以用同一个叶面ascx而有很多种不同的组件调用。可重用就大大的。不仅在同一个项目内重用,而是想用就用。
       实例一下:
       作个无关联cs文件的ascx页面。上面有个button. Id为 mybutton. 当然是run at server我们才能在组件中找到他了!ascx叶面也可以是文本文件。把后缀名改为ascx就行了。
       用我前面写的loadskin来加载吧!然后在里面处理button 的onclick事件就可以了。
然后在aspx中引用这个组件就行了。当然也可以在ascx中引用,都是一个效果。
       Ascx起名为a.ascx. 上面只有一个button
       也是继承 SkinnedControl
namespace Region.Controls {
   
    ///<summary>
    /// 加载用户组件,加载不同的组件
    ///</summary>
    public class Abutton : SkinnedControl {
         Button bt;
        public Abutton() : base()
         {
base .SkinPath = "a.ascx";
         }
 
        ///<summary>
        /// 初始化组建摸板,进行必要的动态设置或更新
        ///</summary>
        override protected void InitializeSkin(Control skin) {
              bt = (Button)skin.FindControl("myButton");
              bt.Click +=new EventHandler(bt_Click);
              skin.DataBind();
        }
       
        ///<summary>
        /// 获取组件
        ///</summary>
        public override ControlCollection Controls {
              get {
                   EnsureChildControls();
                   return base.Controls;
              }
         }
 
         private void bt_Click(object sender, EventArgs e)
         {
              bt.Text = "心雨楼";
         }
     }
}
我么在写个同样的组件叫ebutton 根Abutton一样。
把事件改为 bt.Text = "心雨楼!!!!!!!!";
让我们来看看无代码的aspx是什么样子的!
 
运行之后就这个样子:
分别点击之后就这样:
 
 
相同的页面做不同的事情。
从虚拟机到双系统:手把手教你为Gromacs搭建最强Linux环境(含WSL2、Ubuntu22.04配置) 本文详细指导如何在Windows系统下为Gromacs分子动力学模拟搭建高性能Linux环境,涵盖WSL2Ubuntu22.04双系统配置。通过对比虚拟机、WSL2原生Linux的性能数据,提供GPU加速、内存优化等实用技巧,帮助科研人员提升计算效率。 阅读详情

相关推荐

从“氛围编程“到“智能体工程“:AI编程范式的认知跃迁与工程实践

摘要: 2026年,ClaudeCode负责人鲍里斯·切尔尼提出用“智能体工程”(Agent Engineering)替代流行的“氛围编程”(Vibe Coding),认为后者过于主观,无法体现AI编程的系统化与工程化本质。智能体工程强调记忆系统、工具编排、任务分解、可观测性等核心技术,将AI编程从“玄学辅助”升级为可度量、可规模化的工程学科。本文通过对比术语差异、构建知识体系,并结合代码实例(如带记忆系统的代码生成Agent可观测性系统),展示了智能体工程的实际应用。行业案例(如ClaudeCode的并

yyq916的博客 1034

组件控件用户控件

学习C#

weixin_43737866的博客 1342

Windows系统的Mamba环境配置详细教程(状态空间模型)

causal_conv1d也是安装mamba的依赖必须库。安装完成后,通过pip list可以查看到安装的库。Triton是安装mamba的依赖,需要先安装。上述工作准备好后,按下面步骤安装。直接根据离线文件安装即可。是自己的虚拟环境名字。

2301_77831163的博客 3634

一个使用用户控件(包括组件)的演示。

1.Imports System.ComponentModelPublic Class pic    Inherits System.Windows.Forms.UserControl#Region " Windows 窗体设计器生成的代码 "    UserControl1 重写 dispose 以清理组件列表。    Protected Overloads Overrides Sub Dis

闵峰的专栏 938

动态加载用户控件组件!(终结MasterPages技术)

动态加载用户控件组件!(终结MasterPages技术) 让我们来做个页面模版吧!有了模版是不是就可以统一了呢!Sure !比如:模版页Template.ascx中我们留出中间一个部分,或者你想要留出的一个空间,让以后放入你想要的内容。好了!那么在我们的页面index.aspx上我们就可以引用这个Template.ascx,然后在空出的部分放入我们特别的东西,当然最好是在空的地方

心雨楼 3631

动态加载用户控件组件

我们写用户控件的目的就是放到页面中去。根据不同的条件,我们可以改变加载用户控件!其实原理就是MasterPage的原理。这个MasterPage会在vs2005中提供,但是现在也可以实现。在我的项目中就用到:MasterPage就四个类,其中容器就动态加载用户控件。这种功能在vs2005中将无处不在。下面简单介绍一下动态加载叶面组件:我们只需要改变用户组件的地址就可以动态

zhangqs_1981的专栏 800

动态加载用户控件组件!(三)

     上一篇文章写到动态加载用户控件的简单应用    页面是用来浏览信息的!但是更重要的是用户交互,根据不同的需求提供不同的内容服务,这是一种服务或是一种更贴近用户的人性化。(又在胡言乱语了!^_^)动态加载叶面,根据不同的用户权限加载不懂的内容服务。根据用户的相应加载相应的内容服务。还有另外一个应用就是做到页面与代码的分离。在vs2003里,一般ascx或aspx文件,在刚

心雨楼 4063

动态加载用户控件组件!(四)

       (实在很懒,关于动态加载用户控件的内容实在写也写不完,说也说不完。关系到asp.net的一切!)       我们要做没有关联cs文件的aspx叶面。其实叶面的东西并不在aspx上,而是在ascx上。Aspx所起的作用只是一个入口。对组件的引用而已,而组件就可以管理很多的ascx页面,所谓的叶面ascx叶面也应该是没有关联cs的叶面。       所以整个系统所有的东西都是在

心雨楼 7784

动态加载用户控件组件!(二)

 上一篇文章写到了动态加载用户组件组件。但是怎样灵活的在项目中运用呢?怎样做到面向组件的开发呢?就像是积木式开发,我们的叶面可以有不同的组件来完成,而整个叶面就是一个容器,我们只不过是往容器里添加不同的元素而已,因此只要我们的元素能够做到通用,一般化,那么元素积累到了一定的程度,元素足够的丰富就可以经而一举构造出我们想要得叶面。更多地运用到下一篇文章再详细到来。下面我们先来看看怎么样

心雨楼 6010

C# aspx页面动态加载ascx用户控件 及 利用反射调用其内方法

//控件代码 public partial class WebUserControl : System.Web.UI.UserControl {     public void TestMethod(string strID)     {         this.TextBox1.Text += " WebUserControl:" + strID;         //其他相关操作...

weixin_33754913的博客 190

Web User Control 相关知识汇总(网络联接)

一。心雨楼 http://blog.csdn.net/xinyulou (*****) 1. 动态加载用户控件组件! 2. 动态改变自定义组件! 3. 动态加载用户控件组件!(二) 4. 动态加载用户控件组件!(三) 5. 动态加载用户控件组件!(四) 6. 动态加载用户控件组件!(终结MasterPages技术) 二。笨...

weixin_30416497的博客 65

在UpdatePanel中灵活地切换不同用户控件

 这是一个很常见的使用场景,尤其是出现了UpdatePanel之后:页面中有一排菜单,点击菜单中的每一项,都会使某个UpdatePanel中出现不同的控制面板。在开发时,往往会将每个的控制面板写成不同的用户控件,点击菜单时事实上就是在UpdatePanel中放入不同的用户控件。  如果要开发这样的功能,从理论上来说并不困难,但是如果要能够在控件之间灵活切换,甚至要从控件A的某个操作中切换到控件

刚刚.Net相关知识技术互动平台(粉色回忆) 763
上一篇: 图片上传的实现
下一篇: vs的使用
Awinye
博客等级 码龄21年 13粉丝 122原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值