实现icallbackeventhandlre,以userControl返回做视图层

 1.继承TemplateControl/usercontrol/page中的一个,因为是要回传的视图状态,所以选择了usercontrol,比较适合定义视图状态

public class BaseUserControl:UserControl
    {
        private Control skin;
        public Control Skin { get { return skin; } }
        public BaseUserControl()
        {

///此处定义了要调用的ascx文件的路径,其中的一切变量希望大家忽略,实在与本例无关
            string path = "{0}MasterPages/{1}/UserControls/{2}.ascx";
            string ascxFileName = this.GetType().Name;
            string virpath = String.Format(path, HttpRuntime.AppDomainAppVirtualPath, StaticMethod.CurrentUser.MasterPage, ascxFileName);
            if (!File.Exists(HttpContext.Current.Server.MapPath(virpath)))
            {///指定的文件如果存在,从此处载入ascx文件
                virpath = String.Format(path, HttpRuntime.AppDomainAppVirtualPath, Gloable.MasterPage, ascxFileName);
                if (!File.Exists(HttpContext.Current.Server.MapPath(virpath)))
                {//如果默认的ascx文件也不存在,则返回一个新的Literalcontrol或抛出异常
                    //throw (new Exception(String.Format(StaticMethod.GetMessage("FileNotFind"), virpath)));
                    Literal lit=new Literal();
                    lit.Text = String.Format("{0} Not Found", virpath);
                    skin = lit;
                }
                else {
                    skin = LoadControl(virpath);
                }
            }
            Controls.Add(skin);
        }
    }

2:ascx文件

<asp:Repeater runat="server" ID="Rep_CacheStrategys">
    <HeaderTemplate>
        <table id="TabCacheStrategys">
        <tr>
            <td>关键字</td>
            <td>说明</td>
            <td>缓存策略</td>
            <td>缓存时间(毫秒)</td>
            <td>缓存代价</td>
        </tr>
    </HeaderTemplate>
    <ItemTemplate>
    <tr>
        <td><asp:Label runat="server" id="Lab_Key" ></asp:Label></td>
        <td><asp:Label runat="server" ID="Lab_Description"></asp:Label></td>
        <td><asp:DropDownList runat="server" ID="DDL_Strategy">
            <asp:ListItem Value="Dependency">依赖缓存</asp:ListItem>
            <asp:ListItem Value="Absolute">绝对缓存</asp:ListItem>
            <asp:ListItem Value="Relative">相对缓存</asp:ListItem>
            <asp:ListItem Value="None">不缓存</asp:ListItem>
        </asp:DropDownList></td>
        <td><asp:TextBox runat="server" ID="TB_Expiration"></asp:TextBox></td>
        <td><asp:DropDownList runat="server" id="DDL_Priority">
            <asp:ListItem Value="NotRemovable">不可移除</asp:ListItem>
            <asp:ListItem Value="AboveNormal">最高优先级</asp:ListItem>
            <asp:ListItem Value="High">略高</asp:ListItem>
            <asp:ListItem Value="Normal">正常</asp:ListItem>
            <asp:ListItem Value="Low">略低</asp:ListItem>
            <asp:ListItem Value="BelowNormal">最低优先级</asp:ListItem>
        </asp:DropDownList></td>
    </tr>
    </ItemTemplate>
    <FooterTemplate>
        </Table>
    </FooterTemplate>
</asp:Repeater>

3.继续baseusercontrol实现usercontrol的展示

 public class CacheStrategys:BaseUserControl
    {
        public CacheStrategys() : base() {

           //实现数据绑定Cacheddatas.CachedData.CacheStragegyCollection是一个CacheStragegyItem数组
    //同样与本例无关,请忽略之
            Repeater Rep_CacheStrategys = (Repeater)Skin.FindControl("Rep_CacheStrategys");
            if (Rep_CacheStrategys != null) {
                Rep_CacheStrategys.ItemDataBound += new RepeaterItemEventHandler(Rep_CacheStrategys_ItemDataBound);
                Rep_CacheStrategys.DataSource = Cacheddatas.CachedData.CacheStragegyCollection;
                Rep_CacheStrategys.DataBind();
            }
        }

        void Rep_CacheStrategys_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            //throw new Exception("The method or operation is not implemented.");
           //实现数据绑定的过程省略

        }
    }

4.好了,我们现在有一个usercontrol了,下一步的目标是从实现了icallbackeventhandler接口的page将它回传给客户端.因为我比较容易忘事,所以一样先做了一个basepage的抽象基类,这一步是可以省略的, 可以直接由page来实现它

public abstract class BasePage:Page,ICallbackEventHandler
    {
        public string _Result;
        public abstract void RaiseCallbackEvent(string arg);
        public abstract string GetCallbackResult();
    }

5实现basepage,可以从RaiseCallbackEvent得到客户端的请求,传回_Result用于展现ascx;

public class AppSettings:BasePage
    {
        public override void RaiseCallbackEvent(string argu)
        {
            try
            {
                String[] args = argu.Split(new char[] { '|' }, 2);
                if (args.Length == 2)
                {
                    string command = args[0];
                    string arg = args[1];
                    switch (command)
                    {//如果传回的是LoadAscxFile|ascxfilename格式的参数.
   //其它的参数格式与本例无关省略之.如果command过多,可以考虑反射
                        case "LoadAscxFile":
                            _Result = LoadAscxFile(arg);
                            break;
                        default:
                            _Result = StaticMethod.GetMessage("BadCommand");
                            break;
                    }
                }
                else
                {
                    _Result = StaticMethod.GetMessage("BadCommand");
                }
            }
            catch (Exception excep) { _Result = excep.ToString(); }
        }

public override string GetCallbackResult()
        {
            return _Result;
        }

  private string LoadAscxFile(string ascxFileName) {
            try {
  //这是一个权限验证,可省略
                if (!StaticMethod.ValidateUserRight(ascxFileName)) {
                    return StaticMethod.GetMessage("InvalidateOperation");
                }
                else
                {
      //由ascxfilename反射得到类实例,比如刚才第2,3步实现的CacheStrategys
      //的表现层和逻辑层(ascx/cs)
                    Type t = Type.GetType("Hubei.Blackant.Controls." + ascxFileName);
                    BaseUserControl buc = (BaseUserControl)Activator.CreateInstance(t);
      //将usercontrol写入到StringWriter,回传
      //在此感谢CSDN社区reaperwu(RQ)的帮助
                    StringWriter sw = new StringWriter();
                    HtmlTextWriter htw = new HtmlTextWriter(sw);
                    buc.RenderControl(htw);
                    return sw.ToString();
                }
            }
            catch (Exception excep){
                return excep.ToString();
            }
        }
6好了,做了一大堆事,事实上我们什么也没有得到,还没有页面来实现它呢,55555,多简单的事让我们弄复杂了
<!--这儿的Inherits由第5步实现,55555,上面没有定义namespace-->
<%@ Page Language="C#" Inherits="Hubei.Blackant.AppSettings" ClassName="AppSettings"%>
<%@ Register TagPrefix="bawc" Namespace="Hubei.Blackant.Controls" Assembly="Hubei.Blackant"%>
<asp:Content ContentPlaceHolderID="HeadTag" runat="server" ID="HeadContext">
<script type="text/javascript">
 <!--
function loadAscxFile(ascxfile){
    var command="LoadAscxFile|"+ascxfile;
    var content=true;//这个content实在不知道有什么用,在ClientScriptManager中要实现
    //但是在服务端并不会被接收,而是直接回传给客户端回叫函数
    <%=ClientScript.GetCallbackEventReference(this,"command","ShowClientContext","content")%>
}
function ShowClientContext(result,context){
 //也许传回context的本意是想让result和context关联,但是总觉得多余
    //很多示例在这儿是用result来改变context的属性
    var ClientContext=document.getElementById("ClientContext");
    ClientContext.innerHTML=result;
}
 //-->
</script>
<a href="javascript:LoadAscxFile('CacheStrategys');">Test</a>
<div id="ClientContext">
</div>
7好了,基本上能用了,我们再来回顾一下整个事件过程,这次倒着来,不是由实现的倒序,而是由事件的激发过程用实先click第6步中的anchor会激发javascript定义的LoadAscxFile,在LoadAscxFile中由ClientScriptManager.GetCallbackEventReference激发服务端事件,也就是第五步中的RaiseCallbackEvent,事件接收了LoadAscxFile|CacheStrategys参数,分解后会调用LoadAscxFile方法,LoadAscxFile由反射得到第3步中定义的CacheStrategys实例,CacheStrategys会调用第2步中的ascx文件做为样式,好了,有了这样的用usercontrol来做表现层之后(个人认为这是个比较合理的选择,其实也可以试着由TempableControl来实现,不知道为什么一开始就想到了UserControl),再回到第LoadAscxFile,它会返回CacheStrategys实例的html格式表现方式,并由RaiseCallbackEvent赋值给_Result,然后由GetCallbackResult返回给客户端,客户端再由ClientScriptManager.GetCallbackEventReference定义的回叫方法,此处是ShowClientContext来实现这个html的展现
ps:祝大家开开心心每一天,重要的是写的不好不要骂我,如有错误请写信给我指正blackant@tt88.cn,另有一个问题想请达人指点,如果usercontrol中定义了javascript,返回是客户端能接收到,但其中的定义无效,可能需要document.write(scriptdefine),但是毕竟这样不合理,有好办法解决的也请一并mail2me

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值