用户控件的使用小结

来源:互联网 发布:java 在线客服 编辑:程序博客网 时间:2024/05/16 05:15

用户控件用在何处:

      ascx用户控件与aspx页面最大的区别在于用户控件可重用。在做web开发的时候,在后台业务上一般都会添加和修改数据,那么如果写aspx的话,要么直接都是做在一个页面上,要么就是写两个aspx,然后互相拷贝,而用ascx的话,就只需要写一个控件,直接给一个属性(或者私有方法,这个下面讨论)即可。相应的在前台网站的显示方面,也有一样的问题,比如说一个页面上有两段数据,可能只是一点点不一样(比如新浪的新闻中的国内新闻和国际新闻,可能就是因为新闻类型的不一样),在这样的情况下,用户控件就可以发挥它本身的作用。

 

用户控件如何使用:

      举个案例来讲,新浪的国内新闻和国际新闻,如果用用户控件的话,后台代码(ascx.cs)一样,只是前端显示的ascx不一样,一般有两种方式去实现,一种就是直接扩展ascx,写两个ascx,把<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="News.ascx.cs" %>中的CodeBehind写成一样,然后再调用不一样的控件,而另一种方式就是调用的时候调用一样的控件,使用控件的皮肤来做,只需要在ascx.cs中写一个属性(比如skinPath),在调用的时候将原有的控件皮肤覆盖(Controls.Clear();Controls.Add(Page.LoadControl(skinPath))。

 

两种控件的区别:

第一种相比第二种而言:优点是不需要重写皮肤,效率上面比第二种会高一点,因为不需要去Control.Clear()以及Controls.Add()这两个步骤;缺点是在程序开发完成部署之后,需求更改的时候,需要在部署环境中编译整个的项目文件。

第二种相比第一种而言:优点是,用重载控件皮肤的方式的话可以实现可配置(比如可以将控件皮肤ascx单文件的路径放在数据库中或者是配置文件中),在页面调用的时候,可以根据需求的变化而变化,改动的内容会比较的少,相应的,在部署环境中,如果需求上需要添加一个用户控件,只需要在页面这一层(web层)去添加一个控件皮肤皮肤即可,完全可以省略编译整个项目的过程;相应的缺点就是效率上差一点点(几乎没有),还有的缺点在下面详细阐述第二种如何开发中讲解。

 

如何更有效的开发第二种控件:

如果写用户控件的话,一般都会先去考虑这个用户控件的“接口”是什么(就是业务上的,在这不讨论),这里的“接口”就是指属性和事件,首先属性的话,一般都是get和set,我之前写属性的时候,经常是用到的属性,直接先写上get,set方法之后再说,但后面去详细的查看这个的时候,发现有些属性它其实只需要get方法,比如说浏览器传参(http://news.sina.com.cn/default.aspx?id=1),那么只需要Request["id"]即可,那么这样的属性是否需要呢,我个人认为不能一概而论,如果以后业务上需要扩展这个ID属性的话,这个属性可以放在这里,而如果完全不可能用到的话,直接写一个私有方法去取得这个ID即可(毕竟这样更符合面向对象的思想)。那么事件的话,在这种开发方法中,如果需要定义这个皮肤里面某个控件的事件的话,需要FindControl之后用委托事件的方式添加方法(_newsList.ItemDataBound+=)或者是提供一个EventHandler事件(EventHandler eventComplete;),让调用这个控件的页面或者是控件去重写(protected void OnEventComplete)。后台一般就是属性和事件比较重要,接下来分析下前端控件皮肤。前端控件皮肤主要是用来展示的,可能就是纯粹是样式或者有些内容显示与否上的不一样而已,接下来举个例子,比如新浪的国内新闻列表控件的皮肤是:

<ul>

<asp:Repeater id="rptNews" runat="server">

    <ItemTemplate>

        <li><%# Eval("NewsTitle")%></li>

    </ItemTemplate>

</asp:Repeater>

</ul>

那么引申一下,如果这个<%# Eval("NewsTitle")%>需要做一些转换呢,比如NewsTitle的长度需要截取一下呢,好吧,可能需要将<li><%# Eval("NewsTitle")%></li>更改为<li><% GetShortTilte("NewsTitle",15) %></li>(这里我不详细讨论是否应该用css来控制截取字符串长度更合理),那么当中的GetShortTitle()方法从何而来呢,一种是直接在这个皮肤里面写asp代码(那么这样的方法是否跟我们的思想有点不一致,我们的思想是显示与逻辑分开,这里的截取字符串只是打个比方),另外一种就是在ascx.cs中写一个public方法,这里又牵涉到ascx后台继承的问题了,如果纯粹是继承UserControl,那么这样的写法一点问题都没有;刚才提到需要调用控件皮肤,那么如果有50个控件,那么是否需要在50个控件里面都写同样的一段,拷贝一下呢,我们可以写一个BaseControl类,来让50个控件来继承一下,如果这样的话,那么在前端所有的控件皮肤也都可以继承BaseControl,这样的话,写皮肤的工作就可以完全交给美工来做了,美工完全都没有必要知道需要具体是怎么实现的以及具体这个皮肤是用在那个页面中的,只需要在皮肤里面写上控制页面显示的代码(可能只需要些html控件,当然这个可能需要开发人员与美工配合),但是如果继承BaseControl这个类的话,又有其他的问题了,使用在控件代码中写的GetShortTilte这个方法调用不到,这个也有几种解决的方法:一种是将上面所说的hmtl控件更改为aspx控件,把aspx控件的赋值啊什么的都放在后台控件代码中实现(通过FindControl的方式去给控件赋属性,但这样的话,是否美工需要去学习下aspx控件了之后再来协助开发呢,还是需要开发人才才能做),另一种是把类似于这样的转换方法都放在BaseControl中(但这样的话,共通的方法放在那还好,但如果有个方法可能就一个控件中实用,这样写是不是又不太符合我们的面向对象的思想了呢。类似的可以重新定义一个类专门放一个CommonMethod类,在控件皮肤中就可以直接调用这个类的方法,比放在BaseControl会好很多),当然还有许多其他的方法可以解决这样的问题,最后总结下用户控件的使用。

 

总结:

上面提到了很多次“一种“,”另一种“主要是想表达实现的方式有很多种,然而如何选取需要根据实际的系统设计的情况而定,每一种都有优点和缺点。总的来说,上面所说的只有一个方法:FindControl。

 

以上都只是我个人对用户控件的理解,可能有不到位的地方,如果各位大牛看到有不正确或者有争议的地方,请不吝赐教(可以给我发送邮件或者Q我)。

原创粉丝点击