【问题标题】:Persisting state of custom ASP.Net control自定义 ASP.Net 控件的持久状态
【发布时间】:2011-11-09 23:08:46
【问题描述】:

我有一个自定义控件,在某种程度上模仿了内置的 ASP.Net CheckboxList 控件。在渲染事件中,我根据控件获取的 DataSource 生成 UL>LI>Checkbox#customId 结构。

我最大的困惑是,即使输入的 HTML 元素在页面上呈现,但在提交回页面时,Request.Form 集合没有与这些输入相关的数据。

所以,我的问题是: 触发 PostBack 后,有没有办法让用户检查输入?

提前致谢, 卡利

【问题讨论】:

  • 您可以选择在渲染以外的地方构建这些控件吗?听起来像是页面生命周期的问题,但我可能搞错了。

标签: asp.net


【解决方案1】:

通常,自定义服务器控件将实现 SaveViewStateLoadViewStateTrackViewState 方法来管理控件的状态。

我不知道你的控件是如何构建的,所以我不能给你确切的代码,但这里是我创建的控件中使用的这些方法的示例:

protected override void LoadViewState(object savedState)
{
    if (savedState != null)
    {
        object[] state = (object[])savedState;

        if (state[0] != null)
            base.LoadViewState(state[0]);
        if (state[1] != null)
            ((IStateManager)ItemStyle).LoadViewState(state[1]);
        if (state[2] != null)
            ((IStateManager)headerStyle).LoadViewState(state[2]);
        if (state[3] != null)
            ((IStateManager)AlternatingItemStyle).LoadViewState(state[3]);
    }
}

protected override object SaveViewState()
{
    object[] state = new object[4];

    state[0] = base.SaveViewState();
    state[1] = itemStyle != null ? ((IStateManager)itemStyle).SaveViewState() : null;
    state[2] = headerStyle != null ? ((IStateManager)headerStyle).SaveViewState() : null;
    state[3] = alternatingItemStyle != null ? ((IStateManager)alternatingItemStyle).SaveViewState() : null;

    return state;
}

protected override void TrackViewState()
{
    base.TrackViewState();

    if (itemStyle != null)
        ((IStateManager)itemStyle).TrackViewState();
    if (headerStyle != null)
        ((IStateManager)headerStyle).TrackViewState();
    if (alternatingItemStyle != null)
        ((IStateManager)alternatingItemStyle).TrackViewState();
}

除了以上方法,如果想从Request对象重新加载信息,可以实现IPostBackDataHandler接口,需要这两个方法:

public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
    string somePostedValue = postCollection["SomePostedValue"];
    string anotherPostedValue = postCollection["AnotherPostedValue"];
}

public virtual void RaisePostDataChangedEvent()
{

}

【讨论】:

    【解决方案2】:

    正如詹姆斯正确指出的那样,这是页面生命周期的问题。

    我最初所做的是通过写入 HTmlTextWriter 来在 Render 方法上编写 UL>LI>Input 结构。虽然此方法实际上创建了预期的 HTML,但在回发时,FORM 属性没有带回任何检查的输入。

    我最终做的是使用 Html 服务器控件在 CreateChildControls 上创建控件。这样,我就能够从 FORM 集合中检索到我正在寻找的信息。

    此外,正如 James 在他的回复中指出的那样,为了将状态从一个请求持续到另一个请求,需要重写 LoadViewState 和 SaveViewState 方法。

    【讨论】:

      猜你喜欢
      • 2011-02-21
      • 1970-01-01
      • 2013-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 2011-10-17
      • 2019-10-28
      相关资源
      最近更新 更多