如何处理复合自定义控件中可绑定模板上放置的子控件的视图状态?

时间:2009-03-19 13:48:57

标签: asp.net custom-server-controls

我有一个复合数据绑定控件,它托管一个IBindableTemplate,并根据某些条件动态加载一个标记到控件中。现在,当这些子控件加载到复合控件中并且回发就在那里时,我失去了子控件的视图状态。有没有办法,我可以在回发上保存子控件的视图状态?

我也参考。使用http://scottonwriting.net/sowblog/posts/2129.aspx对斯科特的解释;但没有用。

2 个答案:

答案 0 :(得分:0)

没有足够的信息。你什么时候创建控件?什么时候将它们添加到Controls集合中?什么是条件,它在回发时会改变吗?

如果在适当的时间添加控件,则会在页面循环结束时自动保存视图状态(回发与否)。

如果您稍后添加控件,在完成所有初始化之后的某些情况下,则为时已晚。

<强>更新

没有代码,很难猜出发生故障的位置。让我们检查一个带有自定义模板的Repeater,它可以根据某些条件加载控件。此示例正在运行,但如果在Page_Load上完成模板分配,则会失败。这与你的情况类似吗?

形式:

<div>
    <asp:Repeater ID="repeater" runat="server" />
    <asp:Button ID="submitButton" runat="server" Text="Submit" onclick="submitButton_Click" />
    <asp:Button ID="postButton" runat="server" Text="PostBack" />
</div>

代码:

public partial class _Default : System.Web.UI.Page
{
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        repeater.ItemTemplate = new MyTemplate();
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        //however, if I was to move repeater.ItemTemplate = new MyTemplate() here
        //it would not reload the view state
        if (!IsPostBack)
        {
            repeater.DataSource = new int[] { 1, 2, 3, 4, 5 };
            repeater.DataBind();
        }
    }

    protected void submitButton_Click(object sender, EventArgs e)
    {
        submitButton.Text = "Do it again";
    }
}

public class MyTemplate : IBindableTemplate, INamingContainer
{
    #region IBindableTemplate Members
    public System.Collections.Specialized.IOrderedDictionary ExtractValues(Control container)
    {
        OrderedDictionary dictionary = new OrderedDictionary();
        return dictionary;
    }
    #endregion

    #region ITemplate Members
    public void InstantiateIn(Control container)
    {
        Label label = new Label();
        label.Text = "Label";
        container.Controls.Add(label);

        TextBox textbox = new TextBox();
        container.Controls.Add(textbox);
    }
    #endregion
}

答案 1 :(得分:0)

你的理论代码几乎接近我的情况,只有一个主要的区别是我没有从IBindable扩展我的模板类,而是我在标记本身提供模板的控制,这是要求。

斯科特还明确表示,如果我们像你一样将控件添加到模板

         #region ITemplate Members
         public void InstantiateIn(Control container)
         {
             Label label = new Label();
             label.Text = "Label";
             container.Controls.Add(label);

             TextBox textbox = new TextBox();
             container.Controls.Add(textbox);
         }
         #endregion

然后视图状态将在每次回发时自动保留。我需要的是允许我的模板在标记中实例化,并且在回发时仍然保持视图状态,并允许我获取控制状态,即使我曾经使用一些不同的数据重新启动模板。