none
在ASP.Net中怎样提取公共代码??????????? RRS feed

  • 问题

  • 大家好,请教一个问题!
    我自己写了一个用户控件,是实现分页的!有“首页”“上一页”“下一页”“尾页”“转到”功能。在每一个要用到分页的页面中,都要在Page_load中写入以下代码:

    /// <summary>
    
        /// 加载事件
    
        /// </summary>
    
        /// <param name="sender"></param>
    
        /// <param name="e"></param>
    
        protected void Page_Load(object sender, EventArgs e)
    
        {
    
            this.PageNavigator1.OnPageChange += new PageChangeHandler(PageNavigator1_PageChange);(重复代码)        
    
            if (!IsPostBack)
    
            {
    
            }
    
        }
    其中很多“重复代码”,请问我如何把这些重复代码放如到一个公共类中(注:我自己在App_Code文件夹中写了一个BasePage类)?????我不想用母版页,可以实现吗?????????

    谢谢^_^
    • 已移动 邹俊才Moderator 2009年8月30日 9:12 (发件人:.NET Framework 一般性问题讨论区)
    • 已编辑 艾边成 2009年8月30日 9:35
    2009年8月30日 3:48

答案

  • 谢谢各位的回答,我想知道的是能不能再简单一点呢?

    在BasePage类中不用定义抽象方法,在子类的Page_Load事件中也不用写

    this.PageNavigator1.OnPageChange += new PageChangeHandler(PageNavigator1_PageChange);     

    而将它写入到BasePage类中。当子类页面执行的时候,公共语言运行时自动执行它,

    请问可以吗??????????
    努力!奋斗

    因为需要在子类网页中摆放用户控件的位置,也就代表分页控件必须在子类中实例化,那么父类是不可能知道子类的实例化的对象。因此几乎不可能实现。但我也只是说几乎,如果您深入到aspx的编译机制内部,还是有可能实现的。毕竟网页是由aspx和cs合并编译的。但我觉得这个过程会很挫败,因为还要考虑分页控件的布局问题。
    其实我上面重构的方法也很简单了,就像您使用用户控件需要拖到相应的子类网页上一样,在这里只是一句话来返回用户控件的实例而已。

    至于PageNavigator1_PageChange这个方法是有可能提升到父类的,主要分析是否有变化点。

    抽象方法是面向对象语言中很强大的功能,也是组件或框架开发中很常见的手法,他代表了变化点。
    有一句话说的好,编程不是魔术。总得有人在适当的地方来完成一些工作。
    整个webform的机制也正好体现这一点。才使得我们在用服务控件时这么方便。
    • 已标记为答案 艾边成 2009年8月30日 12:22
    2009年8月30日 12:07
    版主

全部回复

  •  可以考虑用自定义控件开发
    2009年8月30日 4:16
  • 既然你有BasePage类了,那么把这部分公共内容,提炼出参数,做成一个方法,放到你的BasePage里,然后所有页面从BasePage继承,就可以了吧?这么做有何不妥吗?



    理解的越多,需要记忆的就越少
    2009年8月30日 5:02
    版主
  • 您好,BasePage和自定义控件的方法都可以实现您的要求。两者都需要了解asp.net的网页生命周期。
    考虑到过渡,可以先从BasePage下手,然后慢慢地过渡到自定义控件。
    如果您对自己写的BasePage有疑问,可以把代码贴出来,大家一起来分析。
    2009年8月30日 5:56
    版主
  • 你好,BasePage继承Page,其他页面继承BasePage。然后把你上面的实现放在BasePage的Page_Load事件中。
    jon.valett@gmail.com
    2009年8月30日 9:09
    版主
  • 这是分页用户控件中【前台代码】

    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="DataPager.ascx.cs" Inherits="UserControl_DataPager"
        ClassName="DataPager" %>
    
    <%-- 底部分页条  开始--%>
    <asp:Panel ID="pnDataPager" runat="server" DefaultButton="imgbtnGoPage" >
        <table cellpadding="0" cellspacing="0" style="width: 100%; height: 100%;">
            <tr>
                <td style="width: 50%;" align="center">
                    共有
                    <asp:Literal ID="ltCount" runat="server"></asp:Literal>
                    条记录,当前第
                    <asp:Label ID="ltPageNumber" runat="server"></asp:Label>
                    页,共
                    <asp:Label ID="ltPageCount" runat="server"></asp:Label>
                    页
                </td>
                <td >
                    <asp:ImageButton ID="imgbtnFirstPage" CausesValidation="false" runat="server" 
    
    ImageUrl="~/Web/images/firstPage.gif"
                        Width="37px" Height="15" OnClick="imgbtnFirstPage_Click" />&nbsp;&nbsp;&nbsp;
                    <asp:ImageButton ID="imgbtnBackPage" CausesValidation="false" runat="server" 
    
    ImageUrl="~/Web/images/backPage.gif"
                        Width="43px" Height="15" OnClick="imgbtnBackPage_Click" />&nbsp;&nbsp;&nbsp;
                    <asp:ImageButton ID="imgbtnNextPage" CausesValidation="false" runat="server" 
    
    ImageUrl="~/Web/images/nextPage.gif"
                        Width="43px" Height="15" OnClick="imgbtnNextPage_Click" />&nbsp;&nbsp;&nbsp;
                    <asp:ImageButton ID="imgbtnLastPage" CausesValidation="false" runat="server" 
    
    ImageUrl="~/Web/images/lastPage.gif"
                        Width="37px" Height="15" OnClick="imgbtnLastPage_Click" />&nbsp;&nbsp;&nbsp;
                    转到&nbsp;&nbsp;&nbsp;
                    <asp:TextBox ID="txtPageNumber" runat="server" MaxLength="8" Width="20px" Height="18px"
                        BorderColor="#7aaebd" BorderStyle="Solid" BorderWidth="1px"></asp:TextBox>
                    页&nbsp;&nbsp;&nbsp;
                    <asp:ImageButton ID="imgbtnGoPage" CausesValidation="false" runat="server" ImageUrl="~/Web/images/goPage.gif"
                        Width="37px" Height="15" OnClientClick="return CheckUserInput();" OnClick="imgbtnGoPage_Click" 
    
    />&nbsp;&nbsp;&nbsp;
                </td>
            </tr>
        </table>
    </asp:Panel>
    <%-- 底部分页条  结束--%>
    


    这是分页用户控件【后台代码】

    using System;
    using System.Collections;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;
    
    public delegate void PageChangeHandler(object send, int nPageIndex);
    
    public partial class UserControl_DataPager : System.Web.UI.UserControl
    {
    
        public event PageChangeHandler OnPageChange;
        private int count = 0;
        private int currentPageNumber = 1;
        private int pageCount = 0;
    
        /// <summary>
        /// 总记录数
        /// </summary>
        public int Count
        {
            get
            { 
                return Convert.ToInt32( this.ltCount.Text ); 
            }
            set 
            {
                count = value;
                this.ltCount.Text = count.ToString();
            }
        }
    
        /// <summary>
        /// 当前第几页
        /// </summary>
        public int CurrentPageNumber
        {
            get 
            { 
                return Convert.ToInt32( this.ltPageNumber.Text );
            }
            set 
            {
                currentPageNumber = value;
                this.ltPageNumber.Text = currentPageNumber.ToString();
                this.txtPageNumber.Text = currentPageNumber.ToString();
                if (currentPageNumber < 2)
                {
                    //说明是首页
                    this.imgbtnFirstPage.Enabled = false;
                    this.imgbtnBackPage.Enabled = false;
                }
                else
                {
                    this.imgbtnFirstPage.Enabled = true;
                    this.imgbtnBackPage.Enabled = true;
                }
                if (currentPageNumber >= PageCount)
                {
                    this.imgbtnLastPage.Enabled = false;
                    this.imgbtnNextPage.Enabled = false;
                }
                else
                {
                    this.imgbtnLastPage.Enabled = true;
                    this.imgbtnNextPage.Enabled = true;
                }
            }
        }
    
        /// <summary>
        /// 总页数
        /// </summary>
        public int PageCount
        {
            get 
            { 
                return Convert.ToInt32( this.ltPageCount.Text );
            }
            set
            {
                pageCount = value;
                this.ltPageCount.Text = pageCount.ToString();
                this.txtPageNumber_NumericUpDownExtender.Maximum = pageCount;
            }
        }
    
        protected void Page_Load(object sender, EventArgs e)
        {
    
        }
    
        /// <summary>
        /// 转向首页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void imgbtnFirstPage_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
                OnPageChange(sender, 1);
            }
            catch (Exception)
            {
                throw;
            }
        }
    
        /// <summary>
        /// 上一页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void imgbtnBackPage_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
                int n = Convert.ToInt32(this.ltPageNumber.Text);
                n--;
                OnPageChange(sender, n);
            }
            catch (Exception)
            {
                throw;
            }
        }
        
        /// <summary>
        /// 下一页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void imgbtnNextPage_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
                int n = Convert.ToInt32(this.ltPageNumber.Text);
                n++;
                OnPageChange(sender, n);
            }
            catch (Exception)
            {
                throw;
            }
        }
    
        /// <summary>
        /// 尾页
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void imgbtnLastPage_Click(object sender, ImageClickEventArgs e)
        {
            try
            {
                int n = Convert.ToInt32(this.ltPageCount.Text);
                OnPageChange(sender, n);
            }
            catch (Exception)
            {
                throw;
            }
        }
    
        /// <summary>
        /// 转到
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void imgbtnGoPage_Click(object sender, ImageClickEventArgs e)
        {
            int n = 1;
            try
            {
                n = Convert.ToInt32(this.txtPageNumber.Text);
                int total = Convert.ToInt32(this.ltPageCount.Text.Trim());//得到总页数
                if (n > total)
                {
                    n = total;
                }
                if (n < 1)
                {
                    n = 1;
                }
            }
            catch (Exception)
            {
                //发生异常
                n = Convert.ToInt32(this.ltPageNumber.Text); //转到本页
            }
            OnPageChange(sender, n);
        }
    }
    这是我的BasePage类


    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;
    
    using HR.Models;
    
    /// <summary>
    ///BasePage 的摘要说明
    /// </summary>
    public class BasePage : Page
    {
        protected override void OnPreInit(EventArgs e)
        {
            if(Session["CurrentUser"] == null)
            {
                //判断用户是否登录
                Response.Redirect("~/Default.aspx", true);
            }
            base.OnPreInit(e);
        }
    
        /// <summary>
        /// 对HTML内容进行编码,作为字符串输出
        /// </summary>
        /// <param name="obj">需要编码的Object</param>
        /// <returns></returns>
        public string EnableEncode(Object obj)
        {
            return HttpContext.Current.Server.HtmlEncode(obj.ToString());
        }
    
        /// <summary>
        /// 对HTML内容进行编码并且截取指定长度的字符串
        /// </summary>
        /// <param name="obj">需要编码的Object</param>
        /// <param name="subStringLength">指定截取的长度</param>
        /// <returns></returns>
        public string EnableEncodeAndSubString(Object obj,int subStringLength)
        {
            string result = string.Empty;
            if (obj.ToString().Length > subStringLength)
            {
                result = obj.ToString().Substring(0, subStringLength) + "...";
            }
            else
            {
                result = obj.ToString();
            }
            return HttpContext.Current.Server.HtmlEncode(result);
        }
    
        /// <summary>
        /// 验证当前操作员是否有权限访问某个页面
        /// </summary>
        /// <param name="sysFunId"></param>
        protected void ValidateUserRight(int sysFunId)
        {
            bool flag = false;
            if (Session["CurrentUserRight"] != null)
            {
                List<HRUserRight> list = Session["CurrentUserRight"] as List<HRUserRight>;
                foreach(HRUserRight tempUserRight in list)
                {
                    if (tempUserRight.HRSysFunId == sysFunId)
                    {
                        flag = true;
                        break;
                    }
                }
            }
            if (flag == false)
            {
                ShowRightError();
            }
        }
    
        /// <summary>
        /// 弹出消息并重定向到登陆页面
        /// </summary>
        protected void ShowRightError()
        {
            Response.Write("<script language='javascript' type='text/javascript'>alert('抱歉!您没有该权
    
    限!');window.parent.parent.location.replace('../../Default.aspx');</script>");
        }
    
        /// <summary>
        /// 弹出提示
        /// </summary>
        /// <param name="message">要弹出的信息</param>
        protected void ShowMessage(string message)
        {
            ScriptManager.RegisterStartupScript(Page, this.GetType(), "AddError", "alert('" + message + "');", true);
        }
    
    }
    然后我的每个页面都继承这个BasePage类,然后在页面的Page_Load 事件中写入:

    public partial class Web_UserReAndPu_StatReAndPu : BasePage
    {
    
        /// <summary>
        /// 当前页码
        /// </summary>
        public int PageNumber
        {
            get { return (int)ViewState["PageNumber"]; }
            set { ViewState["PageNumber"] = value; }
        }
    
        /// <summary>
        /// 每页显示的项数
        /// </summary>
        public int PageSize
        {
            get { return (int)ViewState["PageSize"]; }
            set { ViewState["PageSize"] = value; }
        }
    
        private const int sysFunId = 102003;
        
    
        /// <summary>
        /// 加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            this.PageNavigator1.OnPageChange += new PageChangeHandler(PageNavigator1_PageChange);
    
            if (!IsPostBack)
            {
                ValidateUserRight(sysFunId);//验证用户是否具有使用该页面的权限
                try
                {
                    PageSize = Convert.ToInt32(ConfigurationManager.AppSettings["pageSizeInStatReAndPu"]);
                    if (PageSize <= 0)
                    {
                        PageSize = 16;
                    }
                }
                catch (Exception)
                {
                    //发生异常,说明不是数字
                    PageSize = 16;
                }
                PageNumber = 1;//当前页码默认第一页
    
                GetCountAndPageCount(); //从数据库中加载总记录数,计算出总页数
                LoadOnePartOperater();  //从数据库中加载当前页码内的数据
            }
    
        }
    
    	/// <summary>
        /// 查询并绑定
        /// </summary>
        protected void LoadOnePartOperater()
        {
            List<MyStatUserReAndPu> optList = MyStatUserReAndPuManager.GetAllResult(PageNumber,PageSize);
            this.rpList.DataSource = optList; //利用Repeater 显示
            this.rpList.DataBind();
            this.PageNavigator1.CurrentPageNumber = PageNumber;//当前第几页
        }
    
        /// <summary>
        /// 得到总记录数和总页数
        /// </summary>
        protected void GetCountAndPageCount()
        {
            
            int count = MyStatUserReAndPuManager.GetAllResultCount(); //从数据库中得到总记录数
            this.PageNavigator1.Count = count; //把总记录数赋值给分页用户控件
    
            int pageCount = 0;
            if (count % PageSize == 0)
            {
                //刚好
                pageCount = count / PageSize;
            }
            else
            {
                pageCount = (count / PageSize) + 1;
            }
            this.PageNavigator1.PageCount = pageCount; //把总页数赋值给分页用户控件
    
        }
    
    }

    现在呢,我的问题是怎样把重复代码提取出来,比如:

    this.PageNavigator1.OnPageChange += new PageChangeHandler(PageNavigator1_PageChange);

    如果我把重复代码写入到BasePage 的Page_load 事件中的话,那么子类就必须重写父类以便获得不同表中的数据


    请教各位????????????????

    2009年8月30日 9:31
  • 你这方案最初是个有缺陷的方案  用户控件缺点是不能共享的  自定义控件能共享的 提供更灵活模式
    2009年8月30日 9:51
  • 哦!非常感谢


    努力!奋斗
    2009年8月30日 10:03
  • 您好,基类代码参考:粗字部分是增加的,带下划线的是我的注释。
     public abstract class BasePage: System.Web.UI.Page
        {
            //移到基类中
            /// <summary>

            /// 当前页码

            /// </summary>

            public int PageNumber
            {
                get { return (int)ViewState["PageNumber"]; }
                set { ViewState["PageNumber"] = value; }
            }

            /// <summary>

            /// 每页显示的项数

            /// </summary>

            public int PageSize
            {
                get { return (int)ViewState["PageSize"]; }
                set { ViewState["PageSize"] = value; }
            }


            protected override void OnPreInit(EventArgs e)
        {
            if(Session["CurrentUser"] == null)
            {
                //判断用户是否登录
                Response.Redirect("~/Default.aspx", true);
            }
            base.OnPreInit(e);
        }

        /// <summary>

        /// 对HTML内容进行编码,作为字符串输出

        /// </summary>

        /// <param name="obj">需要编码的Object</param>

        /// <returns></returns>

        public string EnableEncode(Object obj)
        {
            return HttpContext.Current.Server.HtmlEncode(obj.ToString());
        }

        /// <summary>

        /// 对HTML内容进行编码并且截取指定长度的字符串

        /// </summary>

        /// <param name="obj">需要编码的Object</param>

        /// <param name="subStringLength">指定截取的长度</param>

        /// <returns></returns>

        public string EnableEncodeAndSubString(Object obj,int subStringLength)
        {
            string result = string.Empty;
            if (obj.ToString().Length > subStringLength)
            {
                result = obj.ToString().Substring(0, subStringLength) + "...";
            }
            else
            {
                result = obj.ToString();
            }
            return HttpContext.Current.Server.HtmlEncode(result);
        }

        /// <summary>

        /// 验证当前操作员是否有权限访问某个页面

        /// </summary>

        /// <param name="sysFunId"></param>

        protected void ValidateUserRight(int sysFunId)
        {
            //bool flag = false;
            //if (Session["CurrentUserRight"] != null)
            //{
            //    List<HRUserRight> list = Session["CurrentUserRight"] as List<HRUserRight>;
            //    foreach(HRUserRight tempUserRight in list)
            //    {
            //        if (tempUserRight.HRSysFunId == sysFunId)
            //        {
            //            flag = true;
            //            break;
            //        }
            //    }
            //}
            //if (flag == false)
            //{
            //    ShowRightError();
            //}
        }

        /// <summary>

        /// 弹出消息并重定向到登陆页面

        /// </summary>

        protected void ShowRightError()
        {
    //        Response.Write("<script language='javascript' type='text/javascript'>alert('抱歉!您没有该权

    //限!');window.parent.parent.location.replace('../../Default.aspx');</script>");
        }

        /// <summary>

        /// 弹出提示

        /// </summary>

        /// <param name="message">要弹出的信息</param>

        protected void ShowMessage(string message)
        {
            ScriptManager.RegisterStartupScript(Page, this.GetType(), "AddError", "alert('" + message + "');", true);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            UserControl_DataPager userControl_DataPager = GetUserControl_DataPager();
            GetUserControl_DataPager().OnPageChange += new PageChangeHandler(Page_change);

            if (!IsPostBack)
            {
                //ValidateUserRight(sysFunId);//验证用户是否具有使用该页面的权限
                try
                {
                    //PageSize = Convert.ToInt32(ConfigurationManager.AppSettings["pageSizeInStatReAndPu"]);
                    if (PageSize <= 0)
                    {
                        PageSize = 16;
                    }
                }
                catch (Exception)
                {
                    //发生异常,说明不是数字
                    PageSize = 16;
                }
                PageNumber = 1;//当前页码默认第一页

                GetCountAndPageCount(); //从数据库中加载总记录数,计算出总页数
                LoadOnePartOperater();  //从数据库中加载当前页码内的数据
            }
        }

        //用钩子方法,下面两个方法将在子类中实现
         protected abstract UserControl_DataPager GetUserControl_DataPager();

        protected abstract void Page_change(object send, int nPageIndex);

       //移动到基类中:   
    /// <summary>

        /// 查询并绑定

        /// </summary>

        protected void LoadOnePartOperater()
        {
            //List<MyStatUserReAndPu> optList = MyStatUserReAndPuManager.GetAllResult(PageNumber, PageSize);
            //this.rpList.DataSource = optList; //利用Repeater 显示
            //this.rpList.DataBind();
            //this.PageNavigator1.CurrentPageNumber = PageNumber;//当前第几页
        }

        /// <summary>

        /// 得到总记录数和总页数

        /// </summary>

        protected void GetCountAndPageCount()
        {

            int count = 0;
            //count = MyStatUserReAndPuManager.GetAllResultCount(); //从数据库中得到总记录数
            GetWebUserControlPaging().Count = count; //把总记录数赋值给分页用户控件

            int pageCount = 0;
            if (count % PageSize == 0)
            {
                //刚好
                pageCount = count / PageSize;
            }
            else
            {
                pageCount = (count / PageSize) + 1;
            }
            GetWebUserControlPaging().PageCount = pageCount; //把总页数赋值给分页用户控件

        }

    }

    2009年8月30日 10:57
    版主
  • 这样在子类页面中就变成:

    public partial class Web_UserReAndPu_StatReAndPu : BasePage
    {

            protected void Page_Load(object sender, EventArgs e)
            {


            }
            protected override UserControl_DataPager GetUserControl_DataPager()
            {

                  return this.PageNavigator1;

            }

            protected override void Page_change(object send, int nPageIndex)
            {
               
            }
    }


    总的指导思路,采用设计模式中的模板方法和钩子方法。主要分析哪些是变化的,哪些是不变的。变化的部分可以推迟到子类实现。
    2009年8月30日 11:01
    版主
  • 你这方案最初是个有缺陷的方案  用户控件缺点是不能共享的  自定义控件能共享的 提供更灵活模式

    准确来说,我认为是不能在多个web应用程序或网站中共享。使用了自定义控件还是不能排除要重复写对事件绑定的处理。
    楼主的问题应该是两部分组成
    1、使用BasePage可以重构出重复的部分。
    2、从用户控件过渡到自定义控件,以达到多个web程序的共享。
    2009年8月30日 11:06
    版主
  • 谢谢各位的回答,我想知道的是能不能再简单一点呢?

    在BasePage类中不用定义抽象方法,在子类的Page_Load事件中也不用写

    this.PageNavigator1.OnPageChange += new PageChangeHandler(PageNavigator1_PageChange);     

    而将它写入到BasePage类中。当子类页面执行的时候,公共语言运行时自动执行它,

    请问可以吗??????????
    努力!奋斗
    2009年8月30日 11:44
  • 谢谢各位的回答,我想知道的是能不能再简单一点呢?

    在BasePage类中不用定义抽象方法,在子类的Page_Load事件中也不用写

    this.PageNavigator1.OnPageChange += new PageChangeHandler(PageNavigator1_PageChange);     

    而将它写入到BasePage类中。当子类页面执行的时候,公共语言运行时自动执行它,

    请问可以吗??????????
    努力!奋斗

    因为需要在子类网页中摆放用户控件的位置,也就代表分页控件必须在子类中实例化,那么父类是不可能知道子类的实例化的对象。因此几乎不可能实现。但我也只是说几乎,如果您深入到aspx的编译机制内部,还是有可能实现的。毕竟网页是由aspx和cs合并编译的。但我觉得这个过程会很挫败,因为还要考虑分页控件的布局问题。
    其实我上面重构的方法也很简单了,就像您使用用户控件需要拖到相应的子类网页上一样,在这里只是一句话来返回用户控件的实例而已。

    至于PageNavigator1_PageChange这个方法是有可能提升到父类的,主要分析是否有变化点。

    抽象方法是面向对象语言中很强大的功能,也是组件或框架开发中很常见的手法,他代表了变化点。
    有一句话说的好,编程不是魔术。总得有人在适当的地方来完成一些工作。
    整个webform的机制也正好体现这一点。才使得我们在用服务控件时这么方便。
    • 已标记为答案 艾边成 2009年8月30日 12:22
    2009年8月30日 12:07
    版主
  • 非常感谢您这么热心的回答,谢谢!

    希望看到中国软件的红旗插入到世界的各个角落,

    中国程序员加油!!!!!!!!!!!!!!!!!!!!
    努力!奋斗
    2009年8月30日 12:22
  • 非常感谢您这么热心的回答,谢谢!

    希望看到中国软件的红旗插入到世界的各个角落,

    中国程序员加油!!!!!!!!!!!!!!!!!!!!
    努力!奋斗

    哈,加油!共同努力!
    2009年8月30日 12:34
    版主