0

我有一个应用程序,我需要将多个(和嵌套的)控件添加到 PlaceHolder。用户输入“周数”,我的应用程序添加了一个 RadSplitter(使用 Telerik 控件集),以及相关的窗格/网格。我使用后面的代码添加这些控件。

这在第一次绑定时工作正常(输入周数并单击提交时)。但我还需要在控件之间启用拖放功能,这会导致回发。

我的占位符中的控件数量似乎在回发时始终为“0”,所以我猜测它们没有存储在 ViewState 中。我如何确保我的控件存储在 ViewState 中,而不必在每次回发时都阅读这些内容?

这是一些示例代码:

      protected void btnSubmit_Click(object sender, EventArgs e)
        {
            if (plcSplitter.Controls.Count > 0)
                plcSplitter.Controls.Remove(plcSplitter.Controls[0]);
            var splitter = new Telerik.Web.UI.RadSplitter();
            splitter.Width = Unit.Percentage(100);
            int noOfWeeks = int.Parse(txtNoOfWeeks.Text);
            DateTime dt = new DateTime(2012, 05, 13);
            for (int i = 0; i < noOfWeeks; i++)
            {
                var range = new Common.DateRange(dt.AddDays(-6),dt);
                var pane = new Telerik.Web.UI.RadPane();
                Label lbl = new Label();
                lbl.ID = "lblText";
                lbl.Text = range.To.ToShortDateString();
                pane.Controls.Add(lbl);
                var gv = AddGrid(i);
                pane.Controls.Add(gv);
                splitter.Items.Add(pane);

                var splitLine = new Telerik.Web.UI.RadSplitBar();
            splitter.Items.Add(splitLine);

                dt = dt.AddDays(-7);
            }
            plcSplitter.Controls.Add(splitter);
            splitter.DataBind();
}
4

3 回答 3

2

控件不存储在视图状态中,只有部分控件属性可以存储在视图状态中。因此,在回发时,您必须再次创建这些标签。

将该逻辑从 btnSubmit_Click 创建标签移动到单独的方法,在按钮单击时调用该方法并存储在某处(可能是会话)重新创建标签所需的数据,然后在 OnInit 方法的回发中检查存储的数据,如果有一些标签创建它在那次活动中。

请务必阅读有关 viewstate 的博客文章:

http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx

这是关于在运行时创建控件

http://weblogs.asp.net/infinitiesloop/archive/2006/08/25/TRULY-Understanding-Dynamic-Controls-_2800_Part-1_2900_.aspx

于 2012-05-14T15:46:32.357 回答
1

您可以将构建控件所需的数据存储在 ViewState 中,但真正重要的部分是确保在尝试访问控件之前构建控件。

这是一个超级基本的例子。

    protected void Page_Load(object sender, EventArgs e)
    {
        BuildControl(GetLabelData());
    }

    private Tuple<string, string> GetLabelData()
    {
        if (Page.IsPostBack)
            return (Tuple<string, string>)ViewState["MyLabelData"];
        else
            return new Tuple<string, string>("lblTest", "Test");
    }

    private void BuildControl(Tuple<string, string> t)
    {
        Label l = new Label();
        l.ID = t.Item1;
        l.Text = t.Item2;
        ViewState["MyLabelData"] = t;
        plcSplitter.Controls.Add(l);
    }

    protected void bDoSomething_Click(object sender, EventArgs e)
    {
        Response.Write(String.Format("plcSplitter.Controls.Count:{0}", plcSplitter.Controls.Count));
    }

同样重要的是要认识到这些控件是在服务器上构建的,如果它们可以被客户端更改,您需要为重要的信息位实现一些通信机制,以便您可以重建您的控件,然后应用任何来自客户端的修改。

例如,您正在实现一个可拖动控件,在客户端拖动时,您需要手动将坐标存储在隐藏控件中,以便可以发布回服务器,并且在重建时可以使用该信息控件。

于 2012-05-14T16:10:26.167 回答
0

我认为这些控件未存储在 ViewState 中的原因是,在生成页面 ViewState 之后,它们“为时已晚”被添加到页面中。看看这个帖子:

页面中仍然会影响页面视图状态的最后一个事件

于 2012-05-14T15:41:41.003 回答