5

让我们假设由于某种原因我想创建一个从 Control 而不是 WebControl 派生的自定义控件。我们还假设我需要处理属性(即实现 IAttributeAccessor)并且我想通过使用 AttributeCollection 来完成,就像 WebControl 一样。

WebControl 像这样实现 Attributes 属性:


public AttributeCollection Attributes
{
    get
    {
        if (this.attrColl == null)
        {
            if (this.attrState == null)
            {
                this.attrState = new StateBag(true);
                if (base.IsTrackingViewState])
                {
                    this.attrState.TrackViewState();
                }
            }
            this.attrColl = new AttributeCollection(this.attrState);
        }
        return this.attrColl;
    }
}

请注意以下事项:

  1. 如果不给它一个 StateBag,就无法创建 AttributeCollection。
  2. 我们必须创建一个新的 StateBag。重用控件 StateBag 是不明智的,因为属性可能将名称作为控件存储的值。
  3. 我们不能在 StateBag 上调用 TrackViewState,因为这是一个内部方法。
  4. StateBag 是一个密封类。

因此,据我所知,如果我想使用 AttributeCollection,我必须使用一个新的 StateBag,它永远不能(不使用反射等技巧)真正正确地管理状态。

我错过了什么吗?

4

1 回答 1

3

要在自定义 StateBag 上调用 TrackViewState,您必须将其强制转换为它的接口。

StateBag mybag = new StateBag();
(mybag as IStateManager).TrackViewState();

我猜这个设计决定是为了向消费者隐藏 ViewState 的实现。在IStateManager的文档页面上有一些关于实现自定义状态跟踪的信息。

于 2009-07-21T19:13:19.677 回答