用户控件在回发过程中丢失视图状态
我有一个使用对象作为内部属性的用户控件(下面是一些代码)。
我在以编程方式设置 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 { }
}
I have a user control which uses objects as inner properties (some code is below).
I am having trouble with setting the attribute of the Step class programmatically, when set programmatically it is being lost across postback which would indicate something to do with Viewstate (?).
When setting the property of the Step class declaratively it's working fine.
Does anybody have any ideas of what this code be/what's causing it to lose the state across postback?
ASPX Page
<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 code behind
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.
}
User control code behind
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 { }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您设置的字符串永远不会进入 ViewState。我在这里有点缺乏术语(阅读:我不知道术语),但我认为你的属性
[PersistenceMode(PersistenceMode.Attribute)]
只告诉 ASP.NET 它应该寻找一个名为标记(ASPX 文件)中的“Status”,如果找到,请将属性Status
设置为其值(实际上我想知道它到底放在您的示例中的哪里?)。但它不会告诉任何人将某些内容放入 ViewState 中。如果您按照这些方式定义您的属性
Status
,您的情况应该会更好。
对于其余部分,我不确定您是否必须在 UserControls 中调用
TrackViewState()
甚至重写SaveViewState
和LoadViewState
但我不这样做这么认为。如果是这种情况,以下链接可能会有所帮助:I think the string you set never makes it to the ViewState. I am a bit short of terminology here (read: I do not know the terminology) but I think your attribute
[PersistenceMode(PersistenceMode.Attribute)]
only tells ASP.NET it should look for an attribute called "Status" in the markup (ASPX-file) and if it finds one, set the propertyStatus
to its value (actually I am wondering where exactly it is put in your example?). It does not tell anybody to put something into ViewState though.If you would define your property
Status
along these linesyou should be better off.
For the rest of it I am not sure if you have to call
TrackViewState()
in UserControls or even overrideSaveViewState
andLoadViewState
but I do not think so. If this would be the case the following links might help:它可能与页面中控件的创建顺序有关。如果回发后,控件的创建顺序与第一次加载页面时的顺序不同,则检索视图状态将不适用于这些控件。
如何以编程方式设置步骤的属性?
It might have something to do with the order of the creation of your controls in the page. If after a postback, the controls are not created in the same order as for the first load of the page, then retreiving the viewstate willl not work for those controls.
How do you set the attribute of step programmatically?