• ExtAspNet应用技巧(六) ViewState与动态创建控件



    文章截图 - 更好的排版


    问题描述
    上一篇文章中,首先在页面上以声明的方式定义个工具栏按钮,然后在后台通过编程的方式定义另一个按钮。

    1. Asp.net页面声明:
     <ext:Panel ShowBorder="false" ShowHeader="false" runat="server">
    <ext:Toolbar ID="Toolbar1" runat="server">
    <ext:Button ID="Button1" EnablePostBack="false" OnClientClick="window.open('default.aspx', '_blank');"
    Text="页面声明的按钮" runat="server">
    </ext:Button>
    </ext:Toolbar>
    </ext:Panel>
    

    2. 后台代码:
     protected void Page_Load(object sender, EventArgs e)
    {
    ExtAspNet.Button btn = new Button();
    btn.Text = "获取工具栏按钮个数";
    btn.Click += new EventHandler(btn_Click);
    Toolbar1.Items.Add(btn);
    }
    private void btn_Click(object sender, EventArgs e)
    {
    Alert.Show("工具栏按钮个数:" + Toolbar1.Items.Count);
    }
    

    3. 生成这样的页面:


    后台我试着将动态添加的工具栏按钮放在第一个位置,如下所示
     Toolbar1.Items.Insert(0, btn);
    

    但是当我点击此按钮回发时,报错了:


    解决思路
    首先,我觉得可能是ExtAspNet内部出了问题,经过调试后发现是两个工具栏按钮的视图状态(ViewState)在回发时都丢失了。
    那为什么通过 Items.Add 的方式就可以,而 Items.Insert 的方式ViewState就会丢失呢?
    于是找来一个解析ViewState的小工具 ViewStateDecoder ,查看页面上ViewState:

    从上面的截图中,我发现对两个按钮的ViewState的存取是按照顺序来的,那么会不会通过 Items.Insert 的方式导致视图顺序变化,后台读取时出错呢?

    于是我在网上找到这篇文章:http://msdn.microsoft.com/en-us/library/ms972976.aspx
    我截取了其中一段关于视图状态和动态添加控件的部分:



    从这段描述中,可以得到如下结论:
    • Page_Load是在页面加载视图之后调用的,而Page_Init在加载视图之前调用,因此动态添加控件最好的时机是在Page_Init中。
    • 即使在Page_Load中动态添加的控件,其视图状态也能保持是因为在调用Controls.Add时会递归加载视图状态。
    • 在Page_Load之后动态添加的控件不要改变现有控件的顺序,否则会导致视图状态不能正确加载(因为视图状态是按照其在父控件中的顺序标示的,正如上图所示)。


    解决方案
    有了以上几点做指导,解决方案也就是轻而易举的事了。我们大概有如下三种解决办法:

    1. 第一种就是开篇提到的。在Page_Load中动态添加控件,但是不改变现有控件的顺序。

    2. 在Page_Init中动态添加控件,这里你任意改变现有控件的顺序都行。
     <ext:Panel ShowBorder="false" ShowHeader="false" runat="server">
    <ext:Toolbar ID="Toolbar1" runat="server">
    <ext:Button ID="Button1" EnablePostBack="false" OnClientClick="window.open('default.aspx', '_blank');"
    Text="页面声明的按钮" runat="server">
    </ext:Button>
    </ext:Toolbar>
    </ext:Panel>
    
     protected void Page_Init(object sender, EventArgs e)
    {
    ExtAspNet.Button btn = new Button();
    btn.Text = "获取工具栏按钮个数";
    btn.Click += new EventHandler(btn_Click);
    Toolbar1.Items.Insert(0, btn);
    }
    private void btn_Click(object sender, EventArgs e)
    {
    Alert.Show("工具栏按钮个数:" + Toolbar1.Items.Count);
    }
    


    3. 动态创建所有的控件,这个比较适合在回发时动态创建控件(比如点击个按钮添加一个控件)。
     <ext:Panel ShowBorder="false" ShowHeader="false" runat="server">
    <ext:Toolbar ID="Toolbar1" runat="server">
    </ext:Toolbar>
    </ext:Panel>
    
     protected void Page_Load(object sender, EventArgs e)
    {
    ExtAspNet.Button btn = null;
    btn = new Button();
    btn.Text = "页面声明的按钮";
    btn.EnablePostBack = false;
    btn.OnClientClick = "window.open('default.aspx', '_blank');";
    Toolbar1.Items.Add(btn);
    btn = new Button();
    btn.Text = "获取工具栏按钮个数";
    btn.Click += new EventHandler(btn_Click);
    Toolbar1.Items.Add(btn);
    }
    private void btn_Click(object sender, EventArgs e)
    {
    Alert.Show("工具栏按钮个数:" + Toolbar1.Items.Count);
    }
    


    源代码在位于 http://extaspnet.codeplex.com/ 中的other\menu_dynamic2_run.aspx
  • 相关阅读:
    VC 编译 MATLAB 的 mex 文件
    MATLAB 与 Excel 接口
    MATLAB 编译器的使用
    为什么安装了MinGW之后,还是不能在Matlab中使用mex?
    matlab文件操作
    matlab外部程序接口-excel
    数字图像加密-同态加密方案
    matlab数字图像简单的加密方法
    matlab中矩阵的表示与简单操作
    linux 安装eccodes环境
  • 原文地址:https://www.cnblogs.com/sanshi/p/1543552.html
Copyright © 2020-2023  润新知