【问题标题】:Complicated Viewstate issue on dynamic controls动态控件上复杂的 Viewstate 问题
【发布时间】:2012-03-20 11:07:02
【问题描述】:

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

该控件用于地址验证。

流程是:

  1. 控制显示器。
  2. 用户输入地址信息。
  3. 页面回发,控件根据 Web 服务验证地址信息。
  4. 如果地址不是 100%,它会显示潜在匹配的列表。
  5. 用户选中他们想要接受的复选框旁边的复选框。
  6. 页面回帖

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

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

如果做不到这一点,我怎样才能有效地运行 databind() ?换句话说,我在 oninit 期间没有控制街道/城市/州/邮编的值。那么,如何重新应用视图状态更改?

【问题讨论】:

  • 您当然应该能够获取用户选择的值;它将在 Request.Forms 集合中,因为它是一个复选框。如果您可以抓住该值并继续,您是否需要重建整个控件?
  • @dash:这是可行的。我怎么知道那个复选框的名称?它位于动态加载的用户控件上的中继器内..
  • @dash:我最终使用了你的想法。我遍历 request.forms 寻找以我的复选框名称结尾的字段。一旦我发现我能够测试它并获得一些周围的数据。效果很好。将您的评论移至答案,我会接受。谢谢,

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


【解决方案1】:

大多数控件都呈现为 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.

【讨论】:

  • 在这种情况下,如果提交时复选框不存在也没关系。我只是想找到一个被检查的第一个实例。工作完美。谢谢。
【解决方案2】:

两个重要的事实:

  1. Repeater 项中的控件应该在 OnItemCreated 中创建,而不是 OnItemDataBound
  2. OnItemCreated 在回发期间运行无需调用 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 中的代码运行,它会找出这个用户控件并将其数据绑定到它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-23
    • 2011-03-17
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多