一起谈.NET技术,asp.net控件开发基础(14)

简介:   1.错误的代码,无法解析  首先来看一段简单的代码 正确                                                                        21212                                        ...

  1.错误的代码,无法解析

  首先来看一段简单的代码

 正确
            
< asp:Wizard  ID ="Wizard1"  runat ="server" >
                
< WizardSteps >
                    
< asp:WizardStep  ID ="WizardStep1"  runat ="server"  Title ="Step 1" >
                        21212
</ asp:WizardStep >
                    
< asp:WizardStep  ID ="WizardStep2"  runat ="server"  Title ="Step 2" >
                    
</ asp:WizardStep >
                
</ WizardSteps >
            
</ asp:Wizard >
            错误
            
< asp:Wizard  ID ="Wizard2"  runat ="server" >
                
< asp:WizardStep  ID ="WizardStep1"  runat ="server"  Title ="Step 1" >
                    21212
</ asp:WizardStep >
                
< asp:WizardStep  ID ="WizardStep2"  runat ="server"  Title ="Step 2" >
                
</ asp:WizardStep >
            
</ asp:Wizard >
            
< br  />
            
< br  />
            
< asp:Label  ID ="Label1"  runat ="server"  Text ="Label" >
                
< asp:TextBox  ID ="TextBox2"  runat ="server" ></ asp:TextBox >
            
</ asp:Label >
            
< br  />
            
< asp:TextBox  ID ="TextBox3"  runat ="server" > 12345 </ asp:TextBox >
            
< br  />
            
< asp:Label  ID ="Label2"  runat ="server"  Text ="Label" > 12345 </ asp:Label >
            
< br  />
            
< br  />
            
< asp:TextBox  ID ="TextBox1"  runat ="server" >
        
< asp:Label  runat ="server"  Text ="Label" ></ asp:Label >
            
</ asp:TextBox >

  Wizard为asp.net2.0新增的一个控件,这个页面发生两个错误,如下图

  运行此页面后则会报错,出现以下提示

  分析器错误

  这里有一个问题,.net提供我们控件时,我们已经形成一种定向思维,控件就是那样写的,如DropDownList,其中只能是套<asp:ListItem>的,那我为什么就不能套别的属性呢?Wizard控件为什么就要加一个WizardSteps属性才可以正常运行呢?当我们思考到这里,我们就该寻找答案.

  2.从ParseChildren元数据属性讲起

  从第五篇开始,我们多次用到了ParseChildren此特性.还请大家先看MSDN对其的解释,其有三种情况

  (1)ParseChildren(true)     第5篇我们使用集合属性的时候我们曾经这样定义,如下代码

   [ParseChildren( true )]
    
public   class  Custom: Control
    
{
    }

  (2)ParseChildren(true,"<Default Property>") 第10篇当我们定义集合属性时,我们曾这样定义

  DropItemList为集合属性

   [ParseChildren( true " DropItemList " )]
   
public   class  DropColor:WebControl
    
{
   }

  (3)ParseChildren(false)  这个我们没用过,也是我们要讲的内容,当其内部定义为flase时,那么放在此控件内的元素将被解析成控件,应该说是页分析器ControlBuilder 类.这里大家可以看看MSDN文档对ControlBuilder 类的解释,至少要先知道这一点。默认情况下,页上的每个控件都与一个默认的 ControlBuilder 类关联。 

  下面我们慢慢看下来.

  3.控件与集合属性

  让我们再次回忆一下ParseChildren的用法,本次的示例代码取自asp.net2.0揭密

  (1) ParseChildren(true,"<Default Property>")的使用,此控件实现效果为随机显示一个内部控件内容 。RItem为一个继承Control的控件,其内部未实现任何东西,你可以在其控件内部输出呈现,记得上面说的ControlBuilder 类默认关联
示例一

    [ParseChildren( true " Items " )]
    
public   class  ItemRotator : CompositeControl
    
{
        
private ArrayList _items = new ArrayList();

        [Browsable(
false)]
        
public ArrayList Items
        
{
            
get return _items; }
        }


        
protected override void CreateChildControls()
        
{
            Random rnd 
= new Random();
            
int index = rnd.Next(_items.Count);
            Control item 
= (Control)_items[index];
            
this.Controls.Add(item);
        }

    }


    
public   class  RItem : Control
    
{

    }

  页面代码

     < custom:ItemRotator
        
id ="ItemRotator1"
        Runat
="server" >
        
< custom:ritem  ID ="Item1"  runat ="server" >
            First Item
        
</ custom:ritem >
        
< custom:ritem  ID ="Item2"  runat ="server" >
            Second Item
            
< asp:Calendar
                
id ="Calendar1"
                Runat
="server"   />
        
</ custom:ritem >
        
< custom:ritem  ID ="Item3"  runat ="server" >
            Third Item
        
</ custom:ritem >
    
</ custom:ItemRotator >
    

  效果就不说了,随机显示ritem控件的内容,注意以上控件定义了一个Items集合属性,另外改进的话就是我们第十篇的讲的,为Ritem定义属性,作为一个集合属性,这里就不再列出代码.

  (1)ParseChildren(false)的使用

  此控件未添加属性,而多了一个方法AddParsedSubObject(),控件有默认的页面分析逻辑,重写AddParsedSubObject方法,可以向控件添加子控件

示例二

   [ParseChildren( false )]
    
public   class  ContentRotator : WebControl
    
{

        
protected override void AddParsedSubObject(object obj)
        
{
            
if (obj is Content)
                
base.AddParsedSubObject(obj);
        }


        
protected override void RenderContents(HtmlTextWriter writer)
        
{
            Random rnd 
= new Random();
            
int index = rnd.Next(this.Controls.Count);
            
this.Controls[index].RenderControl(writer);
        }

    }

    [
    ToolboxItem(
false )
    ]
    
public   class  Content : Control
    
{
    }

  页面代码

< custom:ContentRotator
        
id ="ContentRotator1"
        Runat
="server" >
        
< custom:Content
            
id ="Content1"
            Runat
="server" >
            显示的第一项,此不为属性    
        
</ custom:Content >     
        
< custom:Content
            
id ="Content2"
            Runat
="server" >
            显示的第二项,此不为属性
            
< asp:Calendar
                
id ="Calendar1"
                Runat
="server"   />     
        
</ custom:Content >     
        
< custom:Content
            
id ="Content3"
            Runat
="server" >
            显示的第三项,此不为属性  
        
</ custom:Content >   
    
</ custom:ContentRotator >

  注意:ContentRotator无任何属性(其内部添加的为控件),而是用AddParsedSubObject 方法向控件添加了子控件,而不像ItemRotator控件一样,其内部是属性而非控件.

  4.修改默认解析逻辑

  上面已经说过每个控件都有默认的解析逻辑,其通过ControlBuilder 类来实现,可以通过重写其方法来自定义解析逻辑.下面通过一个例子来说明,它把一个控件以自定义标签所代替,以下列出部分代码

示例三

     // 自定义页分析器
     public   class  ServerTabsBuilder : ControlBuilder
    
{
        
public override Type GetChildControlType(string tagName, IDictionary attribs)
        
{
            
if (String.Compare(tagName, "tab"true== 0)
                
return typeof(ServerTab);
            
else
                
return null;
        }

    }


    [ToolboxItem(
false )]
    
public   class  ServerTab : Control
    
{
        
private string _Text;

        
public string Text
        
{
            
get return _Text; }
            
set { _Text = value; }
        }

    }
(1)ServerTabsBuilder类重写了 ControlBuilder类的GetChildControlType 方法  获取与子标记对应的控件类型的 Type在此方法中,其以tab标签代替了ServerTab控件,改写了页分析逻辑 ControlBuilder类常用的还有AllowWhitespaceLiterals 方法 其指定控件之间是否允许存在空白,大家可以重写此方法,然后测试下就明白了。

  (2)定义一个简单的ServerTab控件。还须在父控件中重写AddParsedSubObject方法将ServerTab控件添加到子控件中

        protected override void AddParsedSubObject(object obj)
        
{
            
if (obj is ServerTab)
                
base.AddParsedSubObject(obj);
        }

  (3)最后还需要把控件生成器跟控件关联起来,当然还要设置ParseChildren(false)

    [ControlBuilder( typeof (ServerTabsBuilder))]
    [ParseChildren(
false )]
    
public   class  ServerTabs : WebControl, IPostBackEventHandler
    
{
    }

  好了,这里主要代码就实现了,呈现代码大家可在后面下载,下面看下页面代码

<% --以上省略css代码-- %>
    
< custom:ServerTabs
        
ID ="ServerTabs1"
        Runat
="Server" >
        
< tab  Text ="First Tab" >
        
< asp:Label  ID ="Label1"  runat ="server"  Text ="Label" ></ asp:Label >
          Contents of the first tab
        
</ tab >     
        
< tab  Text ="Second Tab" >
          Contents of the second tab
        
</ tab >     
        
< tab  Text ="Third Tab" >
          Contents of the third tab
        
</ tab >     
    
</ custom:ServerTabs >

  以上镶套代码为tab标签,而非<custom:ServerTabs></custom:ServerTabs>,但实现效果是一样的,只是我们改了默认的页分析逻辑,自定义了控件页生成器(分析器)。看下效果(当重新编译后需要重新启动vs2005才能看到效果)

  好了,这次的主题也讲完了,这里需要注意的是asp.net2.0中复合控件只需要继承CompositeControl类即可。

上一篇:asp.net控件开发基础(13)

下一篇:asp.net控件开发基础(15)
目录
相关文章
|
11月前
|
监控 Cloud Native 测试技术
.NET技术深度解析:现代企业级开发指南
每日激励:“不要一直责怪过去的自己,他曾经站在雾里也很迷茫”。我是蒋星熠Jaxonic,一名在代码宇宙中探索的极客旅人。从.NET Framework到.NET 8,我深耕跨平台、高性能、云原生开发,践行领域驱动设计与微服务架构,用代码书写技术诗篇。分享架构演进、性能优化与AI融合前沿,助力开发者在二进制星河中逐光前行。关注我,共探技术无限可能!
.NET技术深度解析:现代企业级开发指南
|
人工智能 芯片
D1net阅闻|OpenAI员工疯狂暗示,内部已成功开发ASI?被曝训出GPT-5但雪藏
D1net阅闻|OpenAI员工疯狂暗示,内部已成功开发ASI?被曝训出GPT-5但雪藏
|
SQL 小程序 API
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
717 0
|
Linux API C#
基于 .NET 开发的多功能流媒体管理控制平台
基于 .NET 开发的多功能流媒体管理控制平台
404 9
|
Web App开发 前端开发 调度
一款基于 .NET + Blazor 开发的智能访客管理系统
一款基于 .NET + Blazor 开发的智能访客管理系统
323 8
|
开发框架 算法 .NET
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
361 6
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
1032 0