用户控件在回发过程中丢失视图状态

发布于 2024-08-26 13:59:06 字数 3361 浏览 2 评论 0原文

我有一个使用对象作为内部属性的用户控件(下面是一些代码)。

我在以编程方式设置 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

丢了幸福的猪 2024-09-02 13:59:06

我认为您设置的字符串永远不会进入 ViewState。我在这里有点缺乏术语(阅读:我不知道术语),但我认为你的属性 [PersistenceMode(PersistenceMode.Attribute)] 只告诉 ASP.NET 它应该寻找一个名为标记(ASPX 文件)中的“Status”,如果找到,请将属性 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() 甚至重写 SaveViewStateLoadViewState 但我不这样做这么认为。如果是这种情况,以下链接可能会有所帮助:

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 property Status 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 lines

[PersistenceMode(PersistenceMode.Attribute)]
public string Status
    {
        get
        {
            object o = ViewState["Status"];
            if(o != null) {
                return (string)o;
            }
            return string.Empty;
        }
        set
        {
            ViewState["Status"] = value;
        }
    }

you should be better off.

For the rest of it I am not sure if you have to call TrackViewState() in UserControls or even override SaveViewState and LoadViewState but I do not think so. If this would be the case the following links might help:

终难遇 2024-09-02 13:59:06

它可能与页面中控件的创建顺序有关。如果回发后,控件的创建顺序与第一次加载页面时的顺序不同,则检索视图状态将不适用于这些控件。

如何以编程方式设置步骤的属性?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文