动态控件上的复杂Viewstate问题

时间:2012-03-01 22:08:15

标签: c# asp.net dynamic user-controls

我有一个动态加载的控件,其中包含一个转发器,例如一组文本框。

该控件用于地址验证。

过程是:

  1. 控制显示。
  2. 用户输入地址信息。
  3. 页面发回,控件根据Web服务验证地址信息。
  4. 如果地址不是100%,则会显示潜在匹配列表。 < - 这发生在转发器中。换句话说,它是代码中的数据绑定。
  5. 用户选中他们想要接受的框旁边的框。
  6. 页面帖子回来
  7. 到目前为止,1 - 6工作。问题是当页面回发时,没有转发器项目。

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

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

2 个答案:

答案 0 :(得分:2)

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

部分Web窗体实际上只是所有这些的包装。

每当您需要获取原始值时,您可以在Request.Forms集合中查找使用您要查找的控件的名称回发的任何控件值(通常由asp.net为控件的唯一性生成的唯一ID,以及您的名字。)

这正是您所做的 - 您浏览了Forms集合,查看POST到服务器的原始表单值。它也是您在创建自己的控件时实现IPostBackDataHandler接口时经常执行的操作 - 您从Request.Forms中挖出值。

复选框令人讨厌的是,使用“标准”HTML only get submitted if they are ticked.

答案 1 :(得分:1)

两个重要事实:

  1. Repeater项目中的控件应该在 OnItemCreated OnItemDataBound 中创建。
  2. OnItemCreated 在回发期间运行而必须调用 DataBind()
  3. 我一直在将用户控件加载到转发器项目中,用户控件的类型基于绑定到转发器的数据项。所以我在转发器项目的视图状态中添加了用户控件的类型,以便在回发上运行的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中的代码运行,它会将此用户控件输出并将其数据绑定到它。