我有一个用户控件,它使用对象作为内部属性(下面是一些代码)。
我无法以编程方式设置Step类的属性,当以编程方式设置时,它会在回发时丢失,这表明与Viewstate(?)有关。
以声明方式设置Step类的属性时,它工作正常。
有没有人知道这段代码是什么/导致它在回发中失去状态的原因是什么?
ASPX页面
<uc1:StepControl ID="StepControl1" runat="server">
<Step1 Title="1. Select your Products" Enabled="true">
<Content>
<div class="clearfix">
<div class="floatRight">
<asp:Button ID="btnGoToStep2"
runat="server"
Text="Next"
CausesValidation="false"
OnClick="btnGoToStep2_OnClick" />
</div>
</div>
</Content>
</Step1>
<Step2 Title="2. Select your Features">
<Content>
<div class="clearfix">
<div class="floatLeft">
<asp:Button ID="btnBackToStep1"
runat="server"
Text="Back"
CausesValidation="false"
OnClick="btnBackToStep1_OnClick" />
</div>
<div class="floatRight">
<asp:Button ID="btnGoToStep3"
runat="server"
Text="Next"
CausesValidation="false"
OnClick="btnGoToStep3_OnClick" />
</div>
</div>
</Content>
</Step2>
</uc1:StepControl>
背后的ASPX代码
protected void btnGoToStep2_OnClick(object sender, EventArgs e)
{
StepControl1.Step1.StatusText = "4 Products Selected";
}
protected void btnBackToStep1_OnClick(object sender, EventArgs e)
{
// StatusText (of Step1) gets lost at this point.
}
用户控制代码
public partial class StepControl : System.Web.UI.UserControl
{
[PersistenceMode(PersistenceMode.InnerProperty)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[NotifyParentProperty(true)]
public Step Step1 { get; set; }
[PersistenceMode(PersistenceMode.InnerProperty)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[NotifyParentProperty(true)]
public Step Step2 { get; set; }
protected void Page_Init(object sender, EventArgs e)
{
AddSteps();
}
private void AddSteps() { }
}
[Serializable()]
[ParseChildren(true)]
[PersistChildren(false)]
public class Step
{
[PersistenceMode(PersistenceMode.Attribute)]
public string Title { get; set; }
[PersistenceMode(PersistenceMode.Attribute)]
public string Status { get; set; }
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateInstance(TemplateInstance.Single)]
[TemplateContainer(typeof(StepContentContainer))]
public ITemplate Content { get; set; }
public class StepContentContainer : Control, INamingContainer { }
}
答案 0 :(得分:4)
我认为你设置的字符串永远不会进入ViewState。我在这里的术语有点缺(读:我不知道术语)但我认为你的属性[PersistenceMode(PersistenceMode.Attribute)]
只告诉ASP.NET它应该在标记中寻找一个名为“Status”的属性(ASPX文件) )如果找到一个,将属性Status
设置为其值(实际上我想知道它在您的示例中的确切位置?)。它并没有告诉任何人将某些内容放入ViewState中。
如果您要沿着这些行定义属性Status
[PersistenceMode(PersistenceMode.Attribute)]
public string Status
{
get
{
object o = ViewState["Status"];
if(o != null) {
return (string)o;
}
return string.Empty;
}
set
{
ViewState["Status"] = value;
}
}
你应该过得更好。
对于其余部分,我不确定您是否必须在UserControls中调用TrackViewState()
,甚至覆盖SaveViewState
和LoadViewState
,但我不这么认为。如果是这种情况,以下链接可能有所帮助:
答案 1 :(得分:0)
这可能与页面中控件创建顺序有关。如果在回发之后,控件的创建顺序与第一次加载页面的顺序不同,则retreate viewstate将不适用于这些控件。
如何以编程方式设置步骤的属性?