更高级一点的适配器,web控件开发系列
分类:多线程

  • 控件适配器-初步
  • 控件适配器-更高级一点的适配器
  • 控件适配器-.browser 文件
  • 控件适配器-初步
  • 控件适配器-更高级一点的适配器
  • 控件适配器-.browser 文件

控件在WEB开发时经常要用到,虽然有部分已经存在工具箱里,但有时总需要根据自己的要求,开发一些合适自己的控件。

[源码下载]



服务器控件的开发首先要继承基类,Control,WebControl,CompositeControl,至于这些基类有何特性,大家搜一下。自定义服务器控件的呈现有好几种方法,都是通过Render的方法输出,下面列系Render系列的方法的实现过程。RenderControl,Rednder,RenderBeginTag,RenderContents,RenderEndTag,这几个方法执行的过程是这样,RenderControl会调用Render方法,Render方法再调用RenderBeginTag,RenderContents,RenderEndTag,所以我们在开发的时候直接在RenderBeginTag,RenderContents,RenderEndTag这三个方法里面写代码就可以了。

ASP.NET 2.0中的友好CSS控件适配器的应用 - 用ul、li呈现CheckBoxList和RadioButtonList

在 ASP.NET 中 Label 控件在输出到客户端时是一个 span 控件,ListBox 输出到客户端时是一个 select 控件,BulletedList 输出到客户端时是一个 ul 控件……

上一节讲的用将 BulletedList 转换成 p,这一节讲将其转换成 table。

图片 1图片 2Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

作者:webabcd

也就是说 ASP.NET 的控件和 HTML 控件存在一定的联系,那么我可不可以更改这种联系呢?比如我要把 ASP.NET 中的 Label 控件与 HTML 中的 div 控件对应起来,可不可以呢?

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls.Adapters;

namespace ServerControl
{
    public class RenderOutPut : WebControl
    {
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.Write("博客园");
        }
    }
}

介绍
控件适配器(Control Adapters)可以让你改变通过ASP.NET控件生成的HTML标记。有详细的介绍和示例,但是没有用ul、li呈现CheckBoxList和RadioButtonList的例子(可能是因为太简单了,不屑去写),那就让我们来实现它吧,顺便熟悉一下如何开发控件适配器。

可以的,这就是本节要讨论的内容,我们以 BulletedList 为例,我们不希望 BulletedList 输出的是 ul 列表,而是一项一个段落 p 的形式,这里就不要讨论输出 ul 好还是输出 p 好。

namespace Cftea
{
    public class BulletedListAdapter : WebControlAdapter
    {
        protected override void RenderBeginTag(HtmlTextWriter writer)
        {
            writer.WriteLine();
            writer.WriteBeginTag("table");
            writer.Write(HtmlTextWriter.TagRightChar);
            //base.RenderBeginTag(writer);
        }

这样的控件就以Span输出一个"博客园",你在Default.aspx页面上拖入这个控件,然后运行浏览,查看Html源码:

示例
App_Code/ControlAdaptersSample.cs

首先

        protected override void RenderContents(HtmlTextWriter writer)
        {
            BulletedList bl = Control as BulletedList;
            if (bl != null)
            {
                writer.Indent++;

图片 3图片 4Code
Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ";

图片 5using System;
图片 6using System.Data;
图片 7using System.Configuration;
图片 8using System.Web;
图片 9using System.Web.Security;
图片 10using System.Web.UI;
图片 11using System.Web.UI.WebControls;
图片 12using System.Web.UI.WebControls.WebParts;
图片 13using System.Web.UI.HtmlControls;
图片 14using System.Web.UI.WebControls.Adapters;
图片 15
图片 16图片 17/**//// <summary>
图片 18/// ControlAdaptersSample 的摘要说明
图片 19/// </summary>
图片 20public class ControlAdaptersSample : WebControlAdapter
图片 21图片 22图片 23{
图片 24    protected override void Render(HtmlTextWriter writer)
图片 25图片 26    图片 27{
图片 28        ListControl listControl = this.Control as ListControl;
图片 29        IRepeatInfoUser repeaterInfo = this.Control as IRepeatInfoUser;
图片 30
图片 31        if (listControl == null || repeaterInfo == null)
图片 32图片 33        图片 34{
图片 35            base.Render(writer);
图片 36
图片 37            return;
图片 38        }
图片 39
图片 40        if (listControl.CssClass.Length > 0)
图片 41图片 42        图片 43{
图片 44            writer.AddAttribute("class", listControl.CssClass);
图片 45        }
图片 46
图片 47        writer.RenderBeginTag(HtmlTextWriterTag.Ul);
图片 48
图片 49        for (int i = 0; i < listControl.Items.Count; i++)
图片 50图片 51        图片 52{
图片 53            writer.RenderBeginTag(HtmlTextWriterTag.Li);
图片 54            repeaterInfo.RenderItem(ListItemType.Item, i, new RepeatInfo(), writer);
图片 55            writer.RenderEndTag();
图片 56        }
图片 57
图片 58        writer.RenderEndTag();
图片 59    }
图片 60}
图片 61

我们要建立一个 class 放在 App_Code 文件夹中,这个类的作用就是重写 ASP.NET 控件到 HTML 控件的转换,该类代码如下:

                int i = 0;
                for (i = 0; i < bl.Items.Count; i++)
                {
                    writer.WriteLine();
                    writer.WriteBeginTag("tr");
                    writer.Write(HtmlTextWriter.TagRightChar);

<html xmlns="" >
<head><title>

App_Browsers/ControlAdaptersSample.browser

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls.Adapters;
 
 
namespace Cftea
{
    public class BulletedListAdapter : WebControlAdapter
    {
        protected override void RenderBeginTag(HtmlTextWriter writer)
        {
            //base.RenderBeginTag(writer);
        }

                    writer.WriteLine();
                    writer.Indent++;
                    writer.WriteBeginTag("td");
                    writer.Write(HtmlTextWriter.TagRightChar);
                    writer.Write(bl.Items[i].Text);
                    writer.WriteEndTag("td");

</title></head>
<body>    
    <form name="form1" method="post" action="default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzc1Nzg5MDYwZGS8eaaFjyrhLWbFGOz9cnFT040a+A==" />
</div>

图片 62<browsers>
图片 63  <browser refID="Default">
图片 64    <controlAdapters>
图片 65      <adapter controlType="System.Web.UI.WebControls.CheckBoxList"
图片 66         adapterType="ControlAdaptersSample" />
图片 67      <adapter controlType="System.Web.UI.WebControls.RadioButtonList"
图片 68         adapterType="ControlAdaptersSample" />
图片 69    </controlAdapters>
图片 70  </browser>
图片 71</browsers>
图片 72

        protected override void RenderContents(HtmlTextWriter writer)
        {
            BulletedList bl = Control as BulletedList;
            if (bl != null)
            {
                int i = 0;
                for (i = 0; i < bl.Items.Count; i++)
                {
                    writer.WriteBeginTag("p");
                    writer.Write(HtmlTextWriter.TagRightChar);
                    writer.Write(bl.Items[i].Text);
                    writer.WriteEndTag("p");
                }
            }

                    writer.WriteLine();
                    writer.Indent--;
                    writer.WriteEndTag("tr");
                }
            }
            //base.RenderContents(writer);
        }

         <span id="CC">博客园</span>
    </form>   
</body>
</html>

都有什么browsers可用呢?可以在如下的路径中找到

            //base.RenderContents(writer);
        }

        protected override void RenderEndTag(HtmlTextWriter writer)
        {
            writer.WriteLine();
            writer.Indent--;
            writer.WriteEndTag("table");
            //base.RenderEndTag(writer);
        }
    }
}

RenderBeginTag与RenderEndTag进行重写的方法输出一个超连接类型的控件,在RenderBeginTag里面定义控件的类型,请看下面代码: 

图片 73C:WINDOWSMicrosoft.NETFrameworkv2.0.50727CONFIGBrowsers

        protected override void RenderEndTag(HtmlTextWriter writer)
        {
            //base.RenderEndTag(writer);
        }
    }
}

可以看到新增了一些内容:

图片 74图片 75Code
Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

ControlAdaptersSample.aspx

  • 类名随便起,但该类要继承于 WebControlAdapter,WebControlAdapter 的名称空间是 System.Web.UI.WebControls.Adapters。
  • 重载三个函数:RenderBeginTag,RenderContents,RenderEndTag。
  • 由于我们要全部重写 BulletedList 的输出,所以要在这三个函数中去掉对父类的调用,即程序中注释掉的部分。
  • p 和 ul 不一样,p 是一个项目一个,而 ul 下一级还需要 li,所以我们只需要在 RenderContents 中增加内容。
  • BulletedList bl = Control as BulletedList; as 用于在兼容的引用类型之间执行转换,详情参见 MSDN 的 as(C#).aspx),Control 也即要转换的控件。
  • writer.WriteBeginTag("p"); 写开始标签,自动添加“<”。
  • writer.Write(HtmlTextWriter.TagRightChar); 写“>”,由于 WriteBeginTag 不会自动添加“>”,所以这里要手动写“>”。
  • writer.Write(bl.Items[i].Text); 写每一个 item 的文字。
  • writer.WriteEndTag("p"); 写结束标签,自动添加“<”和“>”。
  • writer.WriteLine();
  • writer.Indent; 代码缩进。

namespace ServerControl
{
    public class RenderOutPut : WebControl
    {
        public override void RenderBeginTag(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Href, "");  //通过HtmlTextWriterAttribute添加属性
            writer.AddStyleAttribute(HtmlTextWriterStyle.Color, "bule");   //通过HtmlTextWriterStyle添加样式
            writer.RenderBeginTag(HtmlTextWriterTag.A);   //通过HtmlTextWriterTag添加控件
        }
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.Write("博客园");
        }
        public override void RenderEndTag(HtmlTextWriter writer)
        {
            writer.RenderEndTag();
        }
    }
}

图片 76图片 77<%图片 78@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="ControlAdaptersSample.aspx.cs"
图片 79    Inherits="Control_ControlAdaptersSample" Title="友好CSS控件适配器的简单示例" %>
图片 80
图片 81<asp:Content ID="Content1" ContentPlaceHolderID="cph" runat="Server">
图片 82图片 83    <style>图片 84
图片 85图片 86        .ListControlCSS {图片 87}{ list-style:none; margin:0px; width: 400px; background-color: #CCC; }
图片 88图片 89        .ListControlCSS INPUT {图片 90}{ background-color: #CCC; }
图片 91图片 92        .ListControlCSS li{图片 93}{ float:left; width:100px; line-height:30px;}
图片 94    </style>
图片 95    <asp:CheckBoxList ID="cbl" runat="server" CssClass="ListControlCSS">
图片 96        <asp:ListItem Text="One" />
图片 97        <asp:ListItem Text="Two" />
图片 98        <asp:ListItem Text="Three" />
图片 99        <asp:ListItem Text="Four" />
图片 100        <asp:ListItem Text="Five" />
图片 101        <asp:ListItem Text="Six" />
图片 102        <asp:ListItem Text="Seven" />
图片 103        <asp:ListItem Text="Eight" />
图片 104        <asp:ListItem Text="Nine" />
图片 105        <asp:ListItem Text="Ten" />
图片 106    </asp:CheckBoxList>
图片 107    <div>
图片 108         </div>
图片 109    <asp:RadioButtonList ID="rbl" runat="server" CssClass="ListControlCSS">
图片 110        <asp:ListItem Text="One" />
图片 111        <asp:ListItem Text="Two" />
图片 112        <asp:ListItem Text="Three" />
图片 113        <asp:ListItem Text="Four" />
图片 114        <asp:ListItem Text="Five" />
图片 115        <asp:ListItem Text="Six" />
图片 116        <asp:ListItem Text="Seven" />
图片 117        <asp:ListItem Text="Eight" />
图片 118        <asp:ListItem Text="Nine" />
图片 119        <asp:ListItem Text="Ten" />
图片 120    </asp:RadioButtonList>
图片 121    <p>
图片 122        官网:<a href="" target="_blank">;
图片 123    </p>
图片 124</asp:Content>
图片 125

然后

有 ASP 编程经验的大概都知道,以上代码和利用 ASP 将数据库中的数据以表格形式输出没有什么两样,并不复杂。

或许你更可以不用那么麻烦,直接在Render里面输出一个控件。

运行结果
CheckBoxList和RadioButtonList将以ul、li呈现

重载类已经写好了,放在 App_Code 目录下,但还需要进一步设置才有效。

生成的 HTML 代码如下:

图片 126图片 127Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

OK
[源码下载]

新建一个 App_Browsers 文件夹,再新建一个 browser 文件,同样文件名并不重要(似乎放在 ASP.NET 文件夹(诸如:App_Browsers、App_Code、App_Themes、bin)下面的文件,其文件名都不重要,重要的是标识、ID、名称空间,并且 ASP.NET 会自动查找、自动更新,应用起来方便得不得了。)

<table>
 <tr>
  <td>Item1</td>
 </tr>
 <tr>
  <td>Item2</td>
 </tr>
 <tr>
  <td>Item3</td>
 </tr>
</table>

namespace ServerControl
{
    public class RenderOutPut : WebControl
    {
        protected override void Render(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Href, "");
            writer.RenderBeginTag(HtmlTextWriterTag.A);
            writer.Write("博客园");
            writer.RenderEndTag();
        }
    }
}

browser 文件的代码如下:

 

直接输出HTML标签也可以实现上面的功能。

<browsers>
    <browser refID="Default">
        <controlAdapters>
            <adapter controlType="System.Web.UI.WebControls.BulletedList"
                     adapterType="Cftea.BulletedListAdapter"></adapter>
        </controlAdapters>
    </browser>
</browsers>

  • 控件适配器-初步
  • 控件适配器-更高级一点的适配器
  • 控件适配器-.browser 文件

图片 128图片 129Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

  • <browser refID="Default"> refID="Default" 表示对于所有的浏览器都应用其 controlAdapters。
  • adapter 的 controlType 表示要转换哪一类控件。
  • adapter 的 adapterType 格式为“名称空间 + 类名”,表示 controlType 交由 adapterType 指示的类处理。

namespace ServerControl
{
    public class RenderOutPut : WebControl
    {
        protected override void Render(HtmlTextWriter writer)
        {
            writer.Write("<a href=";");
        }
    }
}

完成

还有一种方法就是通过RenderControl方法呈现:

此时我们再在 .aspx 中添加一个 BulletedList,输出时,就不再是 ul,而是 p 了。

图片 130图片 131Code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

利用适配器,我们可以把 ASP.NET 的控件映射到 HTML 中的某一类控件,也可以映射到一类我们自己设计的“控件”,比如带选择框的下拉列表框。

namespace ServerControl
{
    public class RenderOutPut : WebControl
    {
        protected override void Render(HtmlTextWriter writer)
        {
            HtmlGenericControl A = new HtmlGenericControl("A");
            A.Attributes.Add("href", "");
            A.Style.Add(HtmlTextWriterStyle.Color, "Blue");
            A.InnerHtml = "博客园(Render)";
            A.RenderControl(writer);
        }
    }
}

我们还将在后面的连载中具体讲解本节步骤的两点内容,尤其是第二点,可以根据不同的浏览器对控件进行不同的转换。

当然RenderControl作为开发服务器控件常用的呈现方法,还有更多的功能,下面给大家介绍一下CreateChildControls与Render结合,输出多个控件组合成的服务器控件

说明

 

上面 WriteBeginTag 更好的做法是使用 RenderBeginTag;而 "p" 也使用 HtmlTextWriterTag.P;WriteEndTag("p") 使用 RenderEndTag() 自动匹配。

图片 132图片 133Code
using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

  • 控件适配器-初步
  • 控件适配器-更高级一点的适配器
  • 控件适配器-.browser 文件

namespace ServerControl
{
    [DefaultProperty ("TextBoxValue")]
    [ToolboxData ("<{0}:RenderOutPut runat=server></{0}:RenderOutPut>")]
    public class RenderOutPut : CompositeControl
    {
        private Label _lblUser;
        private Label _lblPassWrod;
        private TextBox _txtUser;
        private TextBox _txtPassWord;
        private Button _bntOK;
        private Button _bntReset;


        public RenderOutPut()
        { }        

        /// <summary>
        /// 生成控件
        /// </summary>
        protected override void CreateChildControls()
        {
            this.Controls.Clear();

            _lblUser = new Label();
            _lblUser.Text = "用户名: ";
            _lblUser.Height = Unit.Pixel(18);  //高度与长度的数值你们按自己的意愿去调
            _lblUser.ID = "lblUser";
            this.Controls.Add(_lblUser);

            _lblPassWrod = new Label();
            _lblPassWrod.Text = "密 码: ";
            _lblPassWrod.Height = Unit.Pixel(18);
            _lblPassWrod.ID = "lblPassWrod";
            this.Controls.Add(_lblPassWrod);

            _txtUser = new TextBox();
            _txtUser.Width = Unit.Pixel(100);
            _txtUser.Height = Unit.Pixel(18);
            _txtUser.ID = "txtUser1";
            this.Controls.Add(_txtUser);

            _txtPassWord = new TextBox();
            _txtPassWord.Width = Unit.Pixel(100);
            _txtPassWord.TextMode = TextBoxMode.Password;
            _txtPassWord.Height = Unit.Pixel(18);
            _txtPassWord.ID = "txtPassWord";
            this.Controls.Add(_txtPassWord);

            _bntOK = new Button();
            _bntOK.Text = " OK ";
            _bntOK.ID = "bntOK";
            this.Controls.Add(_bntOK);

            _bntReset = new Button();
            _bntReset.Text = "Reset";
            _bntReset.ID = "bntReset";
            this.Controls.Add(_bntReset);

            this.ChildControlsCreated = true;
        }

        protected override void RecreateChildControls()
        {
            if (this.ChildControlsCreated == false)
            {
                base.RecreateChildControls();
            }
        }

        /// <summary>
        /// 输出控件
        /// </summary>
        /// <param name="writer"></param>
        protected override void Render(HtmlTextWriter writer)
        {
                writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
                writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, " 0");
                writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
                writer.RenderBeginTag(HtmlTextWriterTag.Table);

                writer.RenderBeginTag(HtmlTextWriterTag.Tr); //第一行开始
                writer.RenderBeginTag(HtmlTextWriterTag.Td);
                writer.Write("用户注册");
                writer.RenderEndTag();   //第一个单元格结束
                writer.RenderBeginTag(HtmlTextWriterTag.Td);
                writer.Write("");
                writer.RenderEndTag();   //第二个单元格结束
                writer.RenderEndTag();   //第一行结束

                writer.RenderBeginTag(HtmlTextWriterTag.Tr); //第一行开始
                writer.RenderBeginTag(HtmlTextWriterTag.Td);
                this._lblUser.RenderControl(writer);
                writer.RenderEndTag();   //第一个单元格结束
                writer.RenderBeginTag(HtmlTextWriterTag.Td);
                this._txtUser.RenderControl(writer);
                writer.RenderEndTag();   //第二个单元格结束
                writer.RenderEndTag();   //第一行结束

                writer.RenderBeginTag(HtmlTextWriterTag.Tr); //第二行开始
                writer.RenderBeginTag(HtmlTextWriterTag.Td);
                this._lblPassWrod.RenderControl(writer);
                writer.RenderEndTag();   //第一个单元格结束
                writer.RenderBeginTag(HtmlTextWriterTag.Td);
                this._txtPassWord.RenderControl(writer);
                writer.RenderEndTag();   //第二个单元格结束
                writer.RenderEndTag();   //第二行结束

                writer.RenderBeginTag(HtmlTextWriterTag.Tr); //第三行开始
                writer.RenderBeginTag(HtmlTextWriterTag.Td);
                this._bntOK.RenderControl(writer);
                writer.RenderEndTag();   //第一个单元格结束
                writer.RenderBeginTag(HtmlTextWriterTag.Td);
                this._bntReset.RenderControl(writer);
                writer.RenderEndTag();   //第二个单元格结束
                writer.RenderEndTag();   //第三行结束

                writer.RenderEndTag(); //结束table
        }
    }
}

把控件拖进Default.aspx里,运行浏览:

图片 134

上面的代码继承了INamingContainer接口,想知道什么原因的,你可以在代码中去掉这个继承,运行,查看HTML源代码再认真看一下各控件的ID有什么不同就知道了。
它是以this.NamingContainer.ClientID + "_" + this.ID来命名的。
控件的呈现就介绍到这里了。还有多种不同的方法呈现,这需要大家在开发过程合理运用,是面介绍的只是比较常用的方法而已,实现程序的功能有多种方法,大家按自己的意愿去写吧!欢迎大家讨论,也欢迎大家提出更好的呈现方法。也欢迎大家指正文中的错误。因为每天下班回家做饭,吃完都10点了。都是好晚的时候起草的。

下一章介绍一下怎样设置控件的属性。

本文由10bet手机官网发布于多线程,转载请注明出处:更高级一点的适配器,web控件开发系列

上一篇:NET中的命名规范,中的命名真累人 下一篇:没有了
猜你喜欢
热门排行
精彩图文