2009-07-21 71 views
4

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

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,它永远不会(不诉诸像反射这样的技巧)实际上正确地管理状态。

我错过了什么吗?

回答

3

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

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

我猜这个设计决定是为了隐藏消费者ViewState的实现。有关于在documentation page for IStateManager上执行自定义状态跟踪的一些信息。

+0

这是一个调用StateBag的TrackViewState,它是内部的。 – drs9222 2009-07-22 00:03:03