我有一个复合数据绑定控件,它承载一个 IBindableTemplate 并根据某些条件将标记动态加载到控件中。现在,当这些子控件被加载到复合控件中并且回发在那里时,我失去了子控件的视图状态。有没有办法,我可以在回发中保存子控件的视图状态?
我也参考。使用http://scottonwriting.net/sowblog/posts/2129.aspx对 Scott 的解释;但没有用。
我有一个复合数据绑定控件,它承载一个 IBindableTemplate 并根据某些条件将标记动态加载到控件中。现在,当这些子控件被加载到复合控件中并且回发在那里时,我失去了子控件的视图状态。有没有办法,我可以在回发中保存子控件的视图状态?
我也参考。使用http://scottonwriting.net/sowblog/posts/2129.aspx对 Scott 的解释;但没有用。
没有足够的信息。什么时候创建控件?什么时候将它们添加到 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
}
您的理论代码几乎接近我的情况,只有一个主要区别是我没有从 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
然后视图状态将在每次回发时自动持久化。我所需要的只是让我的模板在标记中被实例化,并且在回发时仍然保持视图状态,并允许我获取控制状态,即使我曾经使用一些不同的数据重新启动模板。