ASP.NET Forums
首页 搜索 用户列表 FAQ 注册 登录  
ASP.NET Forums » .Net 专区 » 组件/服务器控件开发 » 关于Web控件集合保存的问题(IStateManager)
  关于Web控件集合保存的问题(IStateManager)
帖子发起人: Rugeo   发起时间: 2005-4-15 3:07 PM   回复数: 2
« 上一主题 下一主题 »
楼主
  2005-4-15, 3:07 PM
Rugeo 离线,最后访问时间: 4/19/2005 4:43:27 PM Rugeo

无等级

士兵
等级: 士兵
注册: 2005年4月15日
积分: 7
精华: 0
发贴: 4
关于Web控件集合保存的问题(IStateManager)
 

正在开发一个Web控件, 但在集合数据保存(ViewState)这个问题上卡住了, 该控件主要是实现集合编辑器及动态增减命令按钮, 在设计时OK, 运行时也可以保存值的修改, 但是无法在运行时增加集合元素(回发后丢失, 集合元素还是在设计时指定的那些), 现附上部分说明问题的源代码文件, 请各位同仁指点迷津.(代码较多, 请见谅)

ItemBase 文件 --  实现IStateManager的Item基类
 /// <summary>
 /// 所有基于控件Item类的基类,实现IStateManger接口
 /// IStateManager接口:定义任何类为支持服务器控件的视图状态管理而必须实现的属性和方法。
 /// </summary>
 public class BaseItem: IStateManager
 {
  public BaseItem()
  {
  }

  private StateBag _ViewState = null;
  protected StateBag ViewState
  {
   get
   {
    if(_ViewState == null)
    {
     _ViewState = new StateBag();
     if(((IStateManager)this).IsTrackingViewState)
      ((IStateManager)_ViewState).TrackViewState();
    }
    return _ViewState;
   }
  }

  public void SetViewStateDirty()
  {
   if (_ViewState != null)
   {
    foreach (StateItem item in ViewState.Values)
    {
     item.IsDirty = true;
    }
   }
  }
  private bool _IsTrackingViewState = false;
  /// <summary>
  /// 获取控件是否在跟踪BaseItem实例的视图状态改变
  /// </summary>
  bool IStateManager.IsTrackingViewState
  {
   get
   {
    return _IsTrackingViewState;
   }
  }

  void IStateManager.TrackViewState()
  {
   ((BaseItem)this).TrackViewState();
  }

  protected virtual void TrackViewState()
  {
   _IsTrackingViewState = true;
   if(_ViewState != null)
   {
    ((IStateManager)_ViewState).TrackViewState();
   }
  }

  object IStateManager.SaveViewState()
  {
   return ((BaseItem)this).SaveViewState();
  }

  protected virtual object SaveViewState()
  {
   if(_ViewState != null)
   {
    return ((IStateManager)_ViewState).SaveViewState();
   }
   return null;
  }

  void IStateManager.LoadViewState(object state)
  {
   ((BaseItem)this).LoadViewState(state);
  }

  protected virtual void LoadViewState(object state)
  {
   if(state != null)
   {
    ((IStateManager)ViewState).LoadViewState(state);
   }
  }
 }


ItemCollectionBase 文件 -- 实现集合编辑器及维护集合中ItemBase视图状态
 [
 Editor(typeof(ItemCollectionEditor), typeof(UITypeEditor)),
 ]
 public class BaseItemCollection: CollectionBase, IStateManager
 {
  public BaseItemCollection()
  {
  }

  private bool _IsTrackingViewState = false;
  bool IStateManager.IsTrackingViewState
  {
   get
   {
    return _IsTrackingViewState;
   }
  }

  public void SetViewStateDirty()
  {
   for(int i = 0; i < List.Count; i++)
   {
    ((BaseItem)List[i]).SetViewStateDirty();
   }
  }

  /// <summary>
  /// 跟踪集合中所有元素的视图状态更改
  /// </summary>
  void IStateManager.TrackViewState()
  {
   _IsTrackingViewState = true;
   foreach(BaseItem Item in List)
   {
    ((IStateManager)Item).TrackViewState();
   }
  }

  /// <summary>
  /// 存储集合中所有元素的视图状态
  /// </summary>
  /// <returns></returns>
  object IStateManager.SaveViewState()
  {
   object[] state = new object[2];
   ArrayList Items;
   ArrayList Indices;
   if(List.Count > 0)
   {
    Items = new ArrayList();
    Indices = new ArrayList();
    for(int i = 0; i < List.Count; i++)
    {
     object Item = ((IStateManager)List[i]).SaveViewState();
     if(Item != null)
     {
      Indices.Add(i);
      Items.Add(Item);
     }
    }
    if(Indices.Count > 0)
    {
     state[0] = Indices;
     state[1] = Items;
    }
   }
   return state;
  }

  void IStateManager.LoadViewState(object state)
  {
   if(state == null)
    return;
   object[] viewState = (object[])state;
   ArrayList Indices = viewState[0] as ArrayList;
   ArrayList Items = viewState[1] as ArrayList;
   if(Items != null)
   {
    for(int i = 0; i < Indices.Count; i++)
    {
     ((IStateManager)List[(int)Indices[i]]).LoadViewState(Items[i]);
    }
   }
  }
 }

继承自ItemBase和ItemCollectionBase的两个类
 public class CommandButton: BaseItem
 {
  public CommandButton(CommandButtonCollection parent)
  {
  }  public CommandButton(): this(null)
  {
  }
  }
 }

 public class CommandButtonCollection: BaseItemCollection
 {
  public CommandButtonCollection(): base()
  {
  }

  public void Add(CommandButton cmdButton)
  {
   List.Add(cmdButton);
   
   if(((IStateManager)this).IsTrackingViewState)
   {
    ((IStateManager)cmdButton).TrackViewState();
    cmdButton.SetViewStateDirty(); //不注释这句, 会引发索引超出的异常, 应该是保存了新增元素的索引值, 但List的Count在下次回发后不变
   }
  }

  public CommandButton this[int Index]
  {
   get
   {
    if(Index >= 0 && Index < base.List.Count)
     return (CommandButton)base.List[Index];
    return null;
   }
  }
 }

下面是控件的部分关键代码:

 [DefaultProperty("Text"),
  ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]
 public class WebCustomControl1 : System.Web.UI.WebControls.WebControl
 {

  private CommandButtonCollection _CommandButtons;

  [
  DefaultValue(null),
  PersistenceMode(PersistenceMode.InnerProperty),
  DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
  NotifyParentProperty(true),
  ]
  public CommandButtonCollection CommandButtons
  {
   get
   {
    if(_CommandButtons == null)
    {
     _CommandButtons = new CommandButtonCollection();
     if(IsTrackingViewState)
     {
      ((IStateManager)_CommandButtons).TrackViewState();
     }
    }
    return _CommandButtons;
   }
  }

  protected override void Render(HtmlTextWriter output)
  {
    ...
 }

  protected override object SaveViewState()
  {
   object[] state = new object[]
    {
     base.SaveViewState(),
     ((IStateManager)CommandButtons).SaveViewState(),  
    };
   return state;
  }

  protected override void TrackViewState()
  {
   base.TrackViewState();
   ((IStateManager)CommandButtons).TrackViewState();
  }

  protected override void LoadViewState(object savedState)
  {
   if(savedState != null)
   {
    object[] state = (object[])savedState;
    base.LoadViewState(state[0]);
    ((IStateManager)CommandButtons).LoadViewState(state[1]);
   }
  }
 }

CommandButtons是一个集合, 维护所有CommandButton,
现在在运行时增加会有索引超出的异常(主要是在LoadViewState的时候, List上一次增加的元素丢失), 不知道问题出在哪了, 请各位同仁指教.


IP 地址: 已登录   来自: 已登录    返回顶部
第 2 楼
  2005-4-15, 4:36 PM
Rugeo 离线,最后访问时间: 4/19/2005 4:43:27 PM Rugeo

无等级

士兵
等级: 士兵
注册: 2005年4月15日
积分: 7
精华: 0
发贴: 4
Re: 关于Web控件集合保存的问题(IStateManager)
 
没人回复吗?
IP 地址: 已登录   来自: 已登录    返回顶部
第 3 楼
  2005-5-30, 8:02 PM
钢盅郭子 离线,最后访问时间: 2/16/2007 1:22:26 AM 钢盅郭子



发帖数前25位
男

连长
等级: 连长
注册: 2004年7月29日
积分: 194
精华: 2
发贴: 161
Re: 关于Web控件集合保存的问题(IStateManager)
 
ViewState这个东东比较难搞
建议先用默认的方式处理好再逐渐加入更多的逻辑
IP 地址: 已登录   来自: 已登录    返回顶部
 第 1 页 总共 1 页 [共有 3 条记录]
ASP.NET Forums » .Net 专区 » 组件/服务器控件开发 » 关于Web控件集合保存的问题(IStateManager)

友情链接: hiDotNet官方论坛 | hiDotNet知识库 | 其它友情链接

Asp.Net Forums version: 2.5.2725
(C)Copyright 2004-2007, hiDotNet.com. All Rights Reserved.
意见反馈 | 关于我们

Powered by Community Server :: Forums 中文本地化: hiDotNet.com