ASP.NET组件设计Step by Step(7)

复杂属性和状态管理

 

复杂属性声明/持久:

所谓复杂属性,即通常不可用CLR的基本数据类型表达的属性。譬如,FontInfo,即代表字体属性,包含Bold NameSizeColor等信息(通常称为子属性)。

对于复杂属性,控件在声明时候,通常采用 属性子属性 的连字符表示复杂属性的一个子属性。

<sdp:TextBox id=”Textbox1” Font-Name=”Vender” Font-Size=”12pt” runat=”server” />

其中的划线部分即代表了Font属性。

复杂属性的另外一种表达是,将复杂属性嵌套放于控件声明标签之中,乘坐 内部属性持久性(inner property persistence )。如:

<asp:DataGrid runat=”Server”>

<HeaderStyle ForeColor=”Red” />

   </asp:DataGrid >

 

复杂属性序列化/持久化的设计时支持

设计时实现是在控件之外实现的,利用元数据(attribute)来实现。对于连字符实现的子属性,经过设定特定的attribute,即可影响设计器从而实现设计时支持。

DesignerSerializationVisibility 实际上在asp.net中是指DesignerSerializationVisibilityAttribute的属性类,通过元数据中指定,并且设为:

DesignerSerializationVisibility.Content可以让设计器知道,应当将复杂属性的内容进行序列化而不是属性本身

DesignerSerializationVisibility.Hidden       让设计器忽略属性和属性内容

DesignerSerializationVisibility.Visible       让设计器以正常方式序列化

       所谓正常方式,就是以字符传、整型如果不属于这些就用字节方式持久化属性(当然对于复杂属性这相当划不来)。

       NotifyParentProperty(true) 表示属性浏览器对控件得此复杂属性的修改可以通告给控件,并告知之上的各个对象(通常会给设计器应用程序),告知属性已经“脏”了。这些约定对控件设计者和设计器开发者以及asp.net页面的开发者都很重要。

      

对于标签嵌套方式的属性持久,应当采用ParseChilren(true)来指定属性的持久,设计器实现嵌套方式则应当指定PersistChildren(false)让设计器将嵌套标签转化为复杂属性的一部分(而不是内嵌的子控件)

 

类型转换器

为了解读复杂属性的持久形式为设计运行时形式,需要对复杂属性指定类型转换器,基本目标是将持久形式解读转换为CLR支持的类型,同时也将属性的CLR类型表达为设计时、运行时的持久形式。即将Font-Size=”8pt”转换为int32 8,将复杂属性的8持久化为Font-Size=”8pt”.

类型转换器的实现不依赖于任何用户界面功能。因此,可在 Windows 窗体和 Web 窗体中应用同一个类型转换器。

类型转换器继承自System.ComponentModel.TypeConverter

实现类型转换器的步骤:

1、 定义一个从 System.ComponentModel.TypeConverter 派生的类。

2、 重写 CanConvertFrom 方法,指定转换器可从中转换的类型。此方法是重载方法。

3、 重写实现转换的 ConvertFrom 方法。此方法是重载方法。

4、 重写 CanConvertTo 方法,指定转换器可转换为的类型。转换为字符串类型不需要重写此方法。此方法是重载方法。

5、 重写实现转换的 ConvertTo 方法。此方法是重载方法。

6、 重写执行验证的 IsValid 方法。此方法是重载方法。

通过TypeConverter(typeof(somecustimoziedTypeConverter))的方式确定某个属性同特定的类型转换器相关。

 

对于asp.net应用来讲,如何保持两个页面间的控件的复杂属性很重要。Control类的默认状态管理交给ViewSatte字典,而复杂属性,使用ViewState时不可能的,这必须用到IstateManager接口参与状态管理。

Interface IstateManager

{

       public bool IsTrackingViewState ; //当由类实现时,获取一个值,通过该值指示服务器控件是否正在跟踪其视图状态更改。

       void LoadViewState(   object state); //当由类实现时,加载服务器控件以前保存的控件视图状态。

object SaveViewState(); //当由类实现时,将服务器控件的视图状态更改保存到 Object

void TrackViewState();//当由类实现时,指示服务器控件跟踪其视图状态更改。

}

ControlViewSatte属性实际上就是一个复杂属性,本质上是一个字典类,通过实现了IstateManager接口参与状态管理(ViewState的细节):

1、 ViewState的数据类型是复杂属性System.Web.UI.StateBag类。实现IstateManager接口的字典。保存多项键/值对,键为字符串,值为对象,当某个对象自动添加到State把实例即ViewState中去时,自动加入一个StateItem对象,存有实际的属性值和相关的布尔标志,知识此属性(StateItem)在初始化后修改过。

2、 在接口的TrackViewState中将此函数的值对应到StateBag的内部布尔变量,如果为真,则当StateItem添加时候(跟踪一个对象的ViewState,或者修改行为,都将StateItem标记为修改过。

3、 SaveViewSate中,枚举项目,创建并返回两个ArrayList分别标记修改过的键和值。

4、 LoadViewSatet执行SaveState的逆操作。

当在ViewSatte中保存属性时候,其状态会自动维护。可以在ViewState中保存任何控减灾往返传送时需要的数(而不是全部数据,从效率考虑剔除冗余数据),且任何保存在ViewState红的数据必须时通过LosFormatter串行化的

所有复杂属性的状态保存应当实现IstateManager来将复杂属性转换为可以在ViewState中保存的简单属性,并且也可以ViewState中保存的简单属性恢复组合为复杂属性。

posted on 2007-06-07 16:18  jasonCao  阅读(202)  评论(0编辑  收藏  举报

导航