Implementing IStateManager in a Custom Type


Implementing IStateManager in a Custom Type

In this section, we'll define a HotSpot class that takes responsibility for managing its own state by implementing the IStateManager interface. The HotSpot class will serve as the base class for types that correspond to circular and rectangular hot spot regions in an image map. In the ImageMap example in the next section, we will use the HotSpot type to define a collection of hot spots in an image map.

Listing 10-11 contains the code for the abstract HotSpot class. Later in this section, you'll see concrete classes that derive from HotSpot , including CircleHotSpot and RectangleHotSpot .

Listing 10-11 HotSpot.cs
 usingSystem; usingSystem.Collections; usingSystem.ComponentModel; usingSystem.Web.UI; namespaceMSPress.ServerControls{ [ TypeConverter(typeof(ExpandableObjectConverter)) ] 
 publicabstractclassHotSpot:IStateManager{ privatebool_isTrackingViewState; privateStateBag_viewState; protectedHotSpot():this(String.Empty,String.Empty){ } protectedHotSpot(stringaction,stringtoolTip){ this.Action=action; this.ToolTip=toolTip; } [ Category("Behavior"), DefaultValue(""), Description("URLfornavigationorargumentforpostbackevent"), NotifyParentProperty(true), ] publicStringAction{ get{ stringaction=(string)(ViewState["Action"]); return(action==null)?String.Empty:action; } set{ ViewState["Action"]=value; } } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] publicabstractMapShapeShape{ get; } [ Category("Behavior"), DefaultValue(""), Description("Tooltiptodisplayoverthehotspot"), NotifyParentProperty(true) ] publicStringToolTip{ get{ stringtip=(string)ViewState["ToolTip"]; return(tip==null)?String.Empty:tip; } set{ ViewState["ToolTip"]=value; } } protectedabstractboolShapeCreated{ get; } [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] protectedStateBagViewState{ get{ if(_viewState==null){ _viewState=newStateBag(false); if(_isTrackingViewState){ ((IStateManager)_viewState).TrackViewState(); } } return_viewState; } } internalvoidSetDirty(){ if(_viewState!=null){ ICollectionKeys=_viewState.Keys; foreach(stringkeyinKeys){ _viewState.SetItemDirty(key,true); } } } publicoverridestringToString(){ returnGetType().Name; } #regionIStatemanagerimplementation boolIStateManager.IsTrackingViewState{ get{ return_isTrackingViewState; } } voidIStateManager.LoadViewState(objectsavedState){ if(savedState!=null){ ((IStateManager)ViewState).LoadViewState(savedState); stringsavedShape=(string)ViewState["Shape"]; if(savedShape!=null){ Shape.LoadFromString(savedShape); } } } objectIStateManager.SaveViewState(){ if(ShapeCreated){ stringcurrentShape=Shape.SaveToString(); stringinitialShape=(string)ViewState["Shape"]; if(currentShape.Equals(initialShape)==false){ ViewState["Shape"]=currentShape; } } if(_viewState!=null){ return((IStateManager)_viewState).SaveViewState(); } returnnull; } voidIStateManager.TrackViewState(){ if(ShapeCreated){ ViewState["Shape"]=Shape.SaveToString(); } _isTrackingViewState=true; if(_viewState!=null){ ((IStateManager)_viewState).TrackViewState(); } } #endregion } } 

HotSpot defines three public properties:

  • Action

    Contains a URL if the hot spot causes navigation and contains a postback argument if the hot spot causes postback.

  • ToolTip

    Allows a page developer to specify a tool tip for the hot spot.

  • Shape

    An abstract property that is overridden by a derived class to return a Shape type such as the MapCircle or MapRectangle types we defined earlier in the chapter, in "Properties and Type Converters."

The most interesting feature of HotSpot is its state management. HotSpot defines a protected ViewState property of type StateBag and delegates state management to it. This is analogous to the default implementation of state management in the Control class and is a convenient technique for implementing state management if you implement a custom type that has several properties. Note, however, that HotSpot is not a Control ; it does not derive from Control or share any other characteristics of the Control class.

HotSpot implements its simple properties (such as Action and ToolTip ) as read-write properties and stores them directly in its ViewState dictionary. HotSpot implements its complex Shape property as a read-only property and performs state management for Shape in its implementation of the IState ­Manager interface.

In the TrackViewState method, HotSpot saves the string representation of the Shape property in its ViewState dictionary and then invokes TrackViewState on its ViewState property. The order of these operations is important and ensures that the initial state of the Shap e property is not marked dirty in ViewState .

In the SaveViewState method, HotSpot checks whether the value of its Shape property differs from the initial state stored in ViewState . If the value does differ , HotSpot stores the new state in ViewState , which ViewState now marks as dirty. HotSpot next invokes SaveViewState on its ViewState property.

In the LoadViewState method, HotSpot first invokes the LoadViewState method on its ViewState property to load state into ViewState . HotSpot then looks up the value of its Shape property in ViewState , and if it finds any saved state, HotSpot uses that saved state to load the state of the Shape property.

Listing 10-12 shows the code for the CircleHotSpot class. The code for the RectangleHotSpot class is similar and is provided in the book's sample files.

Listing 10-12 CircleHotSpot.cs
 usingSystem; usingSystem.ComponentModel; usingSystem.Web.UI; namespaceMSPress.ServerControls{ publicclassCircleHotSpot:HotSpot{ privateMapCircle_circle; publicCircleHotSpot(): this(0,0,0,String.Empty,String.Empty){ } publicCircleHotSpot(intx,inty,intradius,stringaction, stringtoolTip):base(action,toolTip){ if((x!=0)(y!=0)(radius!=0)){ Origin=newMapPoint(x,y); Radius=radius; } } [ Category("Shape"), DefaultValue(typeof(MapPoint),""), Description("Theoriginofthecircularhotspot"), NotifyParentProperty(true) ] publicMapPointOrigin{ get{ return((MapCircle)Shape).Origin; } set{ if(value==null){ thrownewArgumentNullException("value"); } ((MapCircle)Shape).Origin=value; } } [ Category("Shape"), DefaultValue(0), Description("Theradiusofthecircularhotspot"), NotifyParentProperty(true) ] 
 publicintRadius{ get{ return((MapCircle)Shape).Radius; } set{ if(value<0){ thrownewArgumentOutOfRangeException("value"); } ((MapCircle)Shape).Radius=value; } } publicoverrideMapShapeShape{ get{ if(_circle==null){ _circle=newMapCircle(); } return_circle; } } protectedoverrideboolShapeCreated{ get{ return(_circle!=null); } } } } 


Developing Microsoft ASP. NET Server Controls and Components
Developing Microsoft ASP.NET Server Controls and Components (Pro-Developer)
ISBN: 0735615829
EAN: 2147483647
Year: 2005
Pages: 183

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net