You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义SharePoint CheckBoxList提交后Items为空的技术求助

解决自定义ListItemCollection回发后Items为空的问题

首先,咱们得搞清楚问题根源:当你自定义ListItemCollection(也就是你的DialogFieldItemCollection)时,ASP.NET默认的控件状态管理(ViewState)机制没办法自动识别并处理这个自定义集合,所以回发时控件没法从ViewState里恢复Items数据,就导致Items为空了。下面是具体的解决步骤和代码示例:

1. 确保自定义ListItem正确保存自定义属性到ViewState

如果你的集合里是自定义的ListItem(比如DialogFieldItem),首先要让它把自定义属性存入ViewState,这样状态才能被持久化:

public class DialogFieldItem : ListItem
{
    // 自定义属性,用ViewState存储
    public string CustomProperty
    {
        get => (string)ViewState["CustomProperty"] ?? string.Empty;
        set => ViewState["CustomProperty"] = value;
    }
}

2. 让自定义ListItemCollection实现IStateManager接口

ASP.NET的ViewState管理依赖IStateManager接口来保存和恢复状态,所以你的DialogFieldItemCollection必须实现这个接口,才能让集合里的所有Item状态被正确跟踪:

public class DialogFieldItemCollection : ListItemCollection, IStateManager
{
    private readonly StateBag _viewState = new StateBag();
    private bool _isTrackingViewState;

    public DialogFieldItemCollection(ListControl owner) : base(owner) { }

    #region IStateManager实现
    public bool IsTrackingViewState => _isTrackingViewState;

    public void TrackViewState()
    {
        _isTrackingViewState = true;
        // 跟踪每个ListItem的状态
        foreach (DialogFieldItem item in this)
        {
            ((IStateManager)item).TrackViewState();
        }
        _viewState.TrackViewState();
    }

    public object SaveViewState()
    {
        // 保存集合本身的状态和每个Item的状态
        var state = new object[Count + 1];
        state[0] = _viewState.SaveViewState();
        for (int i = 0; i < Count; i++)
        {
            state[i + 1] = ((IStateManager)this[i]).SaveViewState();
        }
        return state;
    }

    public void LoadViewState(object savedState)
    {
        if (savedState == null) return;
        var state = (object[])savedState;
        // 恢复集合和每个Item的状态
        _viewState.LoadViewState(state[0]);
        for (int i = 0; i < Count; i++)
        {
            ((IStateManager)this[i]).LoadViewState(state[i + 1]);
        }
    }
    #endregion
}

3. 自定义CheckBoxList控件,重写Items属性和状态管理方法

接下来,你的自定义CheckBoxList需要重写Items属性,返回你的DialogFieldItemCollection,同时重写状态相关方法,确保集合状态被正确处理:

public class CustomCheckBoxList : CheckBoxList
{
    private DialogFieldItemCollection _items;

    // 重写Items属性,返回自定义集合
    public new DialogFieldItemCollection Items
    {
        get
        {
            if (_items == null)
            {
                _items = new DialogFieldItemCollection(this);
                if (IsTrackingViewState)
                {
                    ((IStateManager)_items).TrackViewState();
                }
            }
            return _items;
        }
    }

    protected override void TrackViewState()
    {
        base.TrackViewState();
        // 开始跟踪自定义集合的状态
        ((IStateManager)_items).TrackViewState();
    }

    protected override object SaveViewState()
    {
        // 合并基础控件状态和自定义集合状态
        var baseState = base.SaveViewState();
        var itemsState = ((IStateManager)_items).SaveViewState();
        return new object[] { baseState, itemsState };
    }

    protected override void LoadViewState(object savedState)
    {
        if (savedState == null)
        {
            base.LoadViewState(null);
            return;
        }
        // 拆分并恢复基础状态和集合状态
        var stateArray = (object[])savedState;
        base.LoadViewState(stateArray[0]);
        ((IStateManager)_items).LoadViewState(stateArray[1]);
    }
}

4. 回发时避免重复绑定数据

最后,在页面或WebPart的代码里,只有在非回发时才绑定数据,否则回发时重新绑定会覆盖ViewState恢复的Items:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        // 首次加载时绑定自定义Items
        var checkBoxList = (CustomCheckBoxList)FindControl("YourCustomCheckBoxList");
        checkBoxList.Items.Add(new DialogFieldItem { Text = "选项1", Value = "1", CustomProperty = "自定义值1" });
        checkBoxList.Items.Add(new DialogFieldItem { Text = "选项2", Value = "2", CustomProperty = "自定义值2" });
    }
}

关键注意点

  • 确保控件的EnableViewState属性为true(默认是true,但若被手动设置为false会导致状态丢失)。
  • 自定义ListItem必须继承自System.Web.UI.WebControls.ListItem,因为它已经实现了IStateManager接口,能自动处理基础状态。

内容的提问来源于stack exchange,提问作者Emaborsa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:57:48