代码之家  ›  专栏  ›  技术社区  ›  Anonymous

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

  •  0
  • Anonymous  · 技术社区  · 16 年前

    我有一个复合数据绑定控件,它承载一个IBindableTemplate,并根据某些条件动态地将标记加载到控件中。现在,当这些子控件被加载到复合控件中并存在回发时,子控件的视图状态将丢失。是否可以在回发时保存子控件的视图状态?

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

    2 回复  |  直到 8 年前
        1
  •  0
  •   Ruslan    16 年前

    信息不足。什么时候创建控件?何时将它们添加到控件集合中?什么是条件,回发时是否会发生变化?

    如果控件是在正确的时间添加的,则视图状态将在页面周期结束时自动保存(回发或不回发)。

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

    更新

    如果没有代码,很难猜测故障发生在哪里。让我们检查一个具有自定义模板的中继器,该模板可以根据某些条件加载控件。此示例正在运行,但如果在页面加载时完成模板分配,则会失败。这和你的情况类似吗?

    形式:

    <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
    }
    
        2
  •  0
  •   mbomb007    8 年前

    您的理论代码几乎接近我的情况,只有一个主要的区别,即我不从IBindable扩展我的模板类,而是为标记本身中的模板提供控件,这是必需的。

    Scott还明确表示,如果我们像您一样将控件添加到模板中

             #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
    

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