关于用户自定义控件,想必大家已经非常熟悉了。虽然说经常用过,但是只是简单的使用而已。在这里再次总结一下Asp.net中的UserControl,以便下次使用时

能够得心应手。本文将会介绍以下内容:


1,什么是UserControl?
2,如何定义一个UserControl?
3,如何使用UserControl?
4,如何通过UserControl属性来控制html?
5,如何实现<u1:Control>string</u1:Control>?

1,什么是UserControl?

关于UserControl的解释MSDN,跟Wikipedia都有介绍:

http://msdn.microsoft.com/en-us/library/system.web.ui.usercontrol.aspx
http://en.wikipedia.org/wiki/ASP.NET#User_controls

说白了,UserControl的存在就是为了重用html代码。有点类似php的include或者require,但是它比include或require更加灵活,它不当只是
单纯的引入代码,而且通过设置UserControl的属性来对html代码进行控制,从而更好的实现代码复用。基本UserControl的使用方法更aspx页面
是一样的,但是UserControl不可以通过url来访问,只能在页面或者其它用户控件中访问。

2,如何定义一个简单UserControl?


新建UserControl方法:右键asp.net web项目->添加->添加新项->Web->Web用户控件。打开控件的后台代码,我们可以看到,控件
继承于System.Web.UI.UserControl类。新建好的控件除了后缀名更asp.net不同之外,其它结构都一样,用法也基本一致。
这是,你就可以在ascx文件添加html代码了。

3,如何使用UserControl?


在页面中使用UserControl只需要在页面的头部添加Register代码段:
<%@ Register src="UserControl/UC_Demo.ascx" tagname="Demo" tagprefix="uc1" %>
src表示用户控件所在的相对路径。
添加完上述代码段之后,就可以你需要使用的地方使用了。
使用方法如下,我们可以看到uc1就是上面定义的tagprefix,Demo就是上面定义的tagname,由于用户控件也是一种服务端控件
因此我们这里必须加上runat="server",否则.net会认为是html标签。
<uc1:Demo ID="aaa" runat="server">
</uc1:Demo>

4,如何自定义属性来控制UserControl的html?


第2,3部分已经介绍了如何新建以及使用一个简单的用户控件。但是,上面的例子只能满足对于简单html的复用,比如说一些
头部信息或底部信息。但对于一些复杂的模块,显然我们需要一些属性来控制它。比如说:我们定义一个用户控件,
该控件需要用户可以自定义主题。即用户希望能够这样的使用:
<uc1:Demo ID="aaa" ThemeName="green" runat="server">
</uc1:Demo>

那么该怎么实现呢?首先,我们的第一印象就是,Theme应该是一个enum类型,可供用户选择,因此,我们首先定义一个Theme的枚举

public enum Theme
     Brown = 10,
     Cyan = 20,
     Gray = 30,
     Green = 40,
      Leaf = 50,
      Plain = 60,
      Purple = 70

    
 OK,枚举有了,那么我们应该如何将该枚举变成UserControl中可设置的选项呢?在UserControl的后台代码中(即ascx.cs文件),
 我们只需为该控件类定义一个public的共有变量即可。因此,我们只要在后台类文件中,添加如下代码就可以实现上述需要:
 public Theme ThemeName;
 我们可以通过私有成员来设置初始值,这时候代码就变成这样:

private Theme _ThemeName = Theme.Cyan;
public Theme ThemeName
     get { return this._ThemeName; }
     set { _ThemeName = value; }

此时,用户可以通过属性来设置Theme了,Theme在页面中设置后,用户控件就可以通过Theme来控制它的html代码中的样式了。

5,如何实现<u1:Control>string</u1:Control>?

 
这个是本文中要讲的重点。在使用用户控件的过程中,有时候是一个模块(如下图),我只需要重用这个框,而这个框里的内容
是要自定义的。那么我们要怎么办呢?首先我们想到的是属性,但是我们不可能将一大串的html代码作为属性传递过去,
这样代码就太恶心了。因此我们就想到了标题的那种方式。将html夹在控件中间。还是接着上面所说的例子,这时,我们希望
用户可以这样调用:

<uc1:Demo ID="aaa" ThemeName="green" runat="server">
 <div style="width:100px;height:100px;backgroud:red;">
  hello world!
</uc1:Demo>

通过google,我找到了解决办法。asp.net提供了ITextControl接口,通过该接口我们就可以实现上述的功能。因此,我们需要做的
就是:第一步,让UserControl实现ITextControl接口。第二步,实现ITextControl的Text字段。第三步,重写Control类中的AddParsedSubObject方法。

假设我们有好几个这样的控件,因此,我们将以上三步实现的内容抽象到一个类中,我们暂且叫做DemoWidget,代码如下:

  [ParseChildren(false)]
    public class DemoWidget : System.Web.UI.UserControl, ITextControl
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public virtual string Text
                object obj2 = this.ViewState["Text"];
                if (obj2 != null)
                    return (string)obj2;
                return string.Empty;
                if (this.HasControls())
                    this.Controls.Clear();
                this.ViewState["Text"] = value;
        protected override void AddParsedSubObject(object obj)
            if (obj is LiteralControl)
                HtmlContent.Append(((LiteralControl)obj).Text);
                this.Text = HtmlContent.ToString();
                if (obj != null)
                    HtmlContent.Append(GetControlHtml(obj as Control));
                    this.Text = HtmlContent.ToString();
        protected StringBuilder HtmlContent = new StringBuilder();
        protected string GetControlHtml(Control ctl)
            StringBuilder sb = new StringBuilder();
            StringWriter tw = new StringWriter();
            HtmlTextWriter writer = new HtmlTextWriter(tw);
            ctl.RenderControl(writer);
            sb.Append(writer.InnerWriter.ToString());
            return sb.ToString();
            //base.AddParsedSubObject(new LiteralControl(tmpStr));
            //this.Text = tmpStr;

我们来看一下,DemoWidget是如何实现上述的三个步骤的。很明显第一步已经完成。

第二步我们可以看到也实现了ITextControl的Text字段,Text字段就是用于保存夹在用户控件中间的文本,从代码中我们可以看到,我将这些文本信息保存到viewstate中。
而Text上方的属性[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
又表示什么呢?msdn的解释如下:
InnerDefaultProperty 指定属性在 ASP.NET 服务器控件中保持为内部文本。还指示将该属性定义为元素的默认属性。只能指定一个属性为默认属性。
http://msdn.microsoft.com/zh-cn/library/system.web.ui.persistencemode.aspx
也就是说,Text将作为DemoWidget的默认属性使用,而且只能有一个这样的属性。

第三步,重写AddParsedSubObject方法
为什么要重新AddParsedSubObject方法呢?我们首先添加一个空的AddParsedSubObject方法,设置一个断点,然后调试,我们可以发现,当DemoWidget中间有文本时,
都会调用该函数,因此,这里我们可以将html赋值给Text。默认,传递进该函数的对象是LiteralControl类型的。因此我们实现如下代码:
该方法的具体解释请查看msdn:http://msdn.microsoft.com/zh-cn/library/system.web.ui.control.addparsedsubobject.aspx
 protected override void AddParsedSubObject(object obj)
 {
   if (obj is LiteralControl)
    {
         this.Text = ((LiteralControl)obj).Text;
    }
 }
 
 这里还需要注意的是:我们必须为DemoWidget类添加属性[ParseChildren(false)],ParseChildren属性表示是否将服务器控件标记内的元素解释为属性,因此,这里应该为false。
 http://msdn.microsoft.com/zh-cn/library/system.web.ui.parsechildrenattribute.aspx
 
 好了,之前提到的三步我们都已经完成了,可是我发现类还有其它代码,其它代码又是干嘛的呢?此时,我们发现如果刚刚三步虽实现了一开始提出的需求,
 但是,上述类还有一定的局限性,就是控件标记内只能包含html文本,当控件标记内需要包含另外一个控件的时候就有问题了。

 <uc1:Demo ID="aaa" ThemeName="green" runat="server">
 <div style="width:100px;height:100px;backgroud:red;">
  hello world!
 <uc1:Demo ID="bbb" ThemeName="Leaf" runat="server">
  <div style="width:100px;height:100px;backgroud:red;">
   hello world!
 </uc1:Demo>
</uc1:Demo>

由于控件标记中包含了其它控件,因此,AddParsedSubObject中的参数obj就有可能是子控件类型,因此我们必须修改AddParsedSubObject函数,并新建HtmlContent成员,用于保存子控件的html代码
然后再将该子控件生成的html代码赋值给控件的Text属性,GetControlHtml方法就是用于获取子控件生成的html代码。而AddParsedSubObject则变成如下所示:

  protected override void AddParsedSubObject(object obj)
            if (obj is LiteralControl)
                HtmlContent.Append(((LiteralControl)obj).Text);
                this.Text = HtmlContent.ToString();
                if (obj != null)
                    HtmlContent.Append(GetControlHtml(obj as Control));
                    this.Text = HtmlContent.ToString();

        
这时,你就可以随意在UserControl标签里添加任何东西了,你可以添加html代码,也可以添加自定义控件,甚至还可以添加asp.net服务端控件。

关于用户自定义控件,想必大家已经非常熟悉了。虽然说经常用过,但是只是简单的使用而已。在这里再次总结一下Asp.net中的UserControl,以便下次使用时能够得心应手。本文将会介绍以下内容:1,什么是UserControl?2,如何定义一个UserControl?3,如何使用UserControl?4,如何通过UserControl属性来控制html?5,如
文章目录前言一、控件分类1.HTML控件2.HTML服务器控件3.ASP.NET服务器控件4.用户控件和自定义控件二、HTML控件和ASP.NET服务器控件1.HTML控件2.ASP.NET服务器控件三、常用服务器控件1.Label控件属性2.Literal控件属性3.TextBox控件属性4.HiddenFiled控件Button控件属性类型5.RadioButton控件6.HyperLink控件四、数据验证控件数据验证方式1.非空验证控件属性2.比较验证控件属性3.范围验证控件属性4.正则表达式验证控件属性5.自定义验证控件属性6.验证信息汇总控件属性 ASP.NETWebForm
[方式一,常用:] 1.新建母版页:在项目上面单击右键→添加→添加新项→模板页。 2.新建子页面:在项目上面单击右键→添加→添加新项→使用母版页的 Web 窗体(针对vs2012),会弹出【选择母版页】选项卡。 3.在母版页里面“挖坑”: 4.要在子页面填
AspNetPager AspNetPager 是 ASP.NET Web 表单应用程序的免费自定义分页控件。 它是中国 ASP.NET 开发人员使用的最流行的第三方 ASP.NET 控件之一。 AspNetPager 于 2003 年首次发布,此后一直在稳步改进和更新。 项目主页: : 在线演示: : 在线文档: :
1、 上章结束的时候已经把整个自定义简单控件的实现都讲好了。打算准备讲复合控件,但是还是有必要把自定义简单控件的流程和生命周期来讲下。 2、 流程: (1) 继承WebControl类,重写RenderContents方法; (2) 设置最外层元素需要重写TagKey属性
ASP.NET Webforms 是一种通过.NET Framework 构建 Web 应用程序的技术。Webforms 提供了一些控件,可以用来构建高可用性、动态和交互式的 Web 应用程序。它为开发者提供了一个简单、可复用的方式,来创建功能强大的 Web 应用程序。 ASP.NET Webforms 使用基于事件的编程模型。开发人员可以使用服务器控件及其事件处理程序,设计 Web 应用程序的用户界面并对用户输入和在服务端执行的事件做出响应。Webform 的优点包括易用性,快速开发和相对简单维护等方面。 ASP.NET Webforms 的开发过程包括以下步骤: 1. 安装 Visual Studio 或其他对 ASP.NET Webforms 的编程环境 2. 创建 Web 应用程序项目并选择 ASP.NET Webforms 模板 3. 设计用户界面,添加控件和应用程序逻辑 4. 发布 Web 应用程序到 Web 服务器上,以便用户可以通过 Web 浏览器访问所开发的应用程序。 开发者可以使用 C# 或 VB.NET 等语言编写 ASP.NET Webforms 应用程序。ASP.NET Webforms 也提供了一些方便实用的控件,如TextBox、DropDownList、GridView、PostBack等,并可集成可用的第三方控件库和组件。 ASP.NET Webforms 学习资料丰富,包括官方文档、教程和开源应用程序示例等。因此,入门 ASP.NET Webforms 开发是快速高效的。
DataTables warning: table id=DataTables_Table_0 - Requested unknown parameter '5' for row 0.解决方案 32119 error: Your local changes to the following files would be overwritten by merge 解决方案 活在影子里: error: Your local changes to the following files would be overwritten by merge 解决方案 想知道这是为啥 error: Your local changes to the following files would be overwritten by merge 解决方案 我把所有的步骤重新来一遍也解决了这个问题表情包 深入理解IEnumerable和IQueryable两接口的区别 u013594653: 写的很清楚,看不懂的只能说明自己还差些火候 error: Your local changes to the following files would be overwritten by merge 解决方案 尘埃里的玄: 你要先把本地的代码给commit啊,stash就是把本地的提交代码给缓存起来