动态控件上的复杂Viewstate问题



我有一个动态加载的控件,它包含一个中继器和其他项目,如一组文本框。

该控件用于地址验证。

过程是:

  1. 控制显示
  2. 用户输入地址信息
  3. 页面返回,控件根据web服务验证地址信息
  4. 如果地址不是100%,则会显示潜在匹配项的列表<-这种情况发生在中继器中。换句话说,它在代码中是数据绑定的
  5. 用户选中要接受的复选框旁边的复选框
  6. 页面向后发布

到目前为止,有1-6个工作。问题是,当页面返回时,没有中继器项目。

如何让中继器加载它的项目而不必运行另一个databind()操作?

如果不能做到这一点,我该如何有效地运行databind()?换句话说,在oninit期间,我没有控制street/city/state/zip值。那么,如何重新应用视图状态更改?

大多数控件都呈现为类似<input type="text" name="myId" id="myId/>的HTML表单元素。

Web表单的一部分实际上只是所有这些的包装。

每当你需要获取原始值时,你只需在Request.Forms集合中查找与你要查找的控件的名称(通常由asp.net为控件的唯一性生成的唯一id和你的名称组成)一起发布的任何控件值。

这正是您所做的——您浏览了Forms集合,查看了发布到服务器的原始表单值。这也是您在创建自己的控件时实现IPostBackDataHandler接口时经常做的事情——您从Request.Forms.中提取值

复选框的烦人之处在于,对于"标准"HTML,只有勾选了复选框,它们才会被提交。

两个重要事实:

  1. 中继器项中的控件应在OnItemCreated中创建,而不是在OnItemDataBound中创建
  2. OnItemCreated在Postback期间运行,而不必调用DataBind()

我一直在将用户控件加载到中继器项目中,用户控件的类型基于绑定到中继器的数据项目。因此,我将用户控件的类型添加到中继器项的视图状态中,以便在回发时运行的OnItemCreated(由于尚未调用DataBind(),因此没有要绑定的数据项)期间,它知道要加载什么类型的用户控件。然后将应用视图状态。

protected void rpTransactions_OnItemCreated(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            var dataItem = e.Item.DataItem;
            string typeName;
            string viewStateKey = string.Concat("typeName", e.Item.ItemIndex);
            if (dataItem == null)
            {
                typeName = ViewState[viewStateKey].ToString();
            }
            else
            {
                typeName = dataItem.GetType().ToString();
                ViewState[viewStateKey] = typeName;
            }
            Control template = TransactionTemplateFactory(typeName);
            template.ID = "trans";
            e.Item.FindControl("phTransSpecific").Controls.Add(template);
        }
    }

如果OnItemDataBound中的代码运行,它会捕获这个用户控件并将其数据绑定到它

最新更新