1. Status Management Overview |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Control. ViewState: The Dictionary of State information. The instance whose ViewState is StateBag. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Manage the view status of ASP. NET Server controls. |
Attributes and methods that must be implemented to support view status management of server controls.
Name |
Description |
LoadViewState |
When implemented by a class, load the control view State previously saved by the server control. |
SaveViewState |
When implemented by the class, the view status of the server control is changed and saved to the Object. |
TrackViewState |
When implemented by a class, it instructs the Server Control to track its view status changes. |
IsTrackingViewState |
Indicates whether the server control is tracking its view status changes. |
|
|
2. How can I manage custom states in a custom control? |
|
|
Overload: LoadViewState and SaveViewState |
|
|
Code 3.1
Using System;
Using System. Collections. Generic;
Using System. Text;
Using System. Web;
Using System. Web. UI;
Namespace AspnetEssential. CustomerControl
{
/// <Summary>
/// BarGraphControl
/// </Summary>
/// <Remarks>
/// Simple chart control. Draw a chart based on the description and values
/// </Remarks>
Public class BarGraphControl: Control
{
/// <Summary>
/// Description list
/// </Summary>
Private List <string> _ description;
/// <Summary>
/// Value List
/// </Summary>
Private List <int> _ values;
/// <Summary>
/// Maximum value (used to calculate the relative length of the BarItem. This function is implemented in this program)
/// </Summary>
Private int _ max;
/// <Summary>
/// Default value of the initialization control in the constructor
/// </Summary>
Public BarGraphControl ()
{
_ Description = new List <string> ();
_ Values = new List <int> ();
}
/// <Summary>
/// Add a key-Value Pair
/// </Summary>
/// <Param name = "name"> </param>
/// <Param name = "value"> </param>
Public void AddItem (string name, int value)
{
_ Description. Add (name );
_ Values. Add (value );
If (value> _ max)
{
_ Max = value;
}
}
# Region State Manager
Protected override object SaveViewState ()
{
Object [] vState = new object [4];
VState [0] = base. SaveViewState ();
VState [1] = _ description;
VState [2] = _ values;
VState [3] = _ max;
Return vState;
}
Protected override void LoadViewState (object savedState)
{
// Base. LoadViewState (savedState );
If (savedState! = Null)
{
Object [] vState = (object []) savedState;
If (vState [0]! = Null)
{
Base. LoadViewState (vState [0]);
}
If (vState [1]! = Null)
{
_ Description = (List <string>) vState [1];
}
If (vState [2]! = Null)
{
_ Values = (List <int>) vState [2];
}
If (vState [3]! = Null)
{
_ Max = (int) vState [3];
}
}
}
# Endregion
# Region Render
/// <Summary>
/// Rendering
/// </Summary>
/// <Param name = "writer"> </param>
Protected override void Render (HtmlTextWriter writer)
{
// Base. Render (writer );
Writer. AddAttribute (HtmlTextWriterAttribute. Id, this. ClientID );
Writer. AddAttribute (HtmlTextWriterAttribute. Bordercolor, "red ");
// The distance between the cell content and the cell border
Writer. addattriding (HtmlTextWriterAttribute. Cellpadding, "0 ");
// Distance between cells
Writer. addattriing (HtmlTextWriterAttribute. Cellspacing, "0 ");
Writer. RenderBeginTag (HtmlTextWriterTag. Table );
// Bar color
String color = string. Empty;
// Draw tr, td
For (int I = 0; I <_ values. Count; I ++)
{
// Tr
Writer. RenderBeginTag (HtmlTextWriterTag. Tr );
// Td
Writer. RenderBeginTag (HtmlTextWriterTag. Td );
Writer. WriteEncodedText (_ description [I]);
Writer. RenderEndTag ();
Writer. RenderBeginTag (HtmlTextWriterTag. Td );
// Writer. addattriattribute (HtmlTextWriterAttribute. Width, _ values [I]. ToString ());
Writer. AddStyleAttribute (HtmlTextWriterStyle. BorderColor, "blue ");
Writer. AddStyleAttribute (HtmlTextWriterStyle. BorderStyle, "solid ");
Writer. AddStyleAttribute (HtmlTextWriterStyle. BorderWidth, "1px ");
Color = (I % 2) = 0? "Red": "blue ");
Writer. AddStyleAttribute (HtmlTextWriterStyle. BackgroundColor, color );
Writer. AddStyleAttribute (HtmlTextWriterStyle. Width, _ values [I]. ToString () + "px ");
Writer. RenderBeginTag (HtmlTextWriterTag. Div );
Writer. RenderEndTag ();
Writer. RenderEndTag ();
Writer. RenderEndTag ();
}
Writer. RenderEndTag ();
}
# Endregion
}
}
3.2 Control Use instance
Private const int MAXCOUNT = 10;
Protected void Page_Load (object sender, EventArgs e)
{
If (! This. IsPostBack)
{
AddBarGraphValue (this. BarGraphControl1 );
}
}
/// <Summary>
/// Generate random data of the control
/// </Summary>
/// <Param name = "barControl"> </param>
Private void AddBarGraphValue (BarGraphControl barControl)
{
Random rd = null;
For (int I = 0; I <MAXCOUNT; I ++)
{
Rd = new Random (I );
Int currentValue = rd. Next (100 );
String title = string. Format ("Item: {0}", I. ToString ());
BarControl. AddItem (title, currentValue );
}
}
3.3 running instructions
After the page executes the post operation, the control status is retained. Shows the effect.
4 problem: Do not use the methods of reloading LoadViewState and SaveViewState. Directly publishing the _ description and other fields as attributes stored in viewstate should also achieve the above effect, when can I manage the status of the overload control?
4.1 experiment code
Using System;
Using System. Collections. Generic;
Using System. Text;
Using System. Web;
Using System. Web. UI;
Namespace AspnetEssential. CustomerControl
{
/// <Summary>
/// BarGraphControl
/// </Summary>
/// <Remarks>
/// Simple chart control. Draw a chart based on the description and values
/// </Remarks>
Public class BarGraphControlWithViewStateProperty: Control
{
/// <Summary>
/// Description list
/// </Summary>
Private List <string> Description
{
Get
{
Return ViewState ["_ description"] as List <string>;
}
Set
{
ViewState ["_ description"] = value;
}
}
/// <Summary>
/// Value List
/// </Summary>
// Private List <int> _ values;
Private List <int> Values
{
Get
{
Return ViewState ["_ values"] as List <int>;
}
Set
{
ViewState ["_ values"] = value;
}
}
/// <Summary>
/// Maximum value (used to calculate the relative length of the BarItem. This function is implemented in this program)
/// </Summary>
// Private int _ max;
Private int Max
{
Get
{
Return (int) ViewState ["_ max"];
}
Set
{
ViewState ["_ max"] = value;
}
}
/// <Summary>
/// Default value of the initialization control in the constructor
/// </Summary>
Public BarGraphControlWithViewStateProperty ()
{
ViewState ["_ description"] = new List <string> ();
ViewState ["_ values"] = new List <int> ();
ViewState ["_ max"] = 0;
}
/// <Summary>
/// Add a key-Value Pair
/// </Summary>
/// <Param name = "name"> </param>
/// <Param name = "value"> </param>
Public void AddItem (string name, int value)
{
Description. Add (name );
Values. Add (value );
If (value> Max)
{
Max = value;
}
}
# Region Render
/// <Summary>
/// Rendering
/// </Summary>
/// <Param name = "writer"> </param>
Protected override void Render (HtmlTextWriter writer)
{
Writer. Write (
String. Format ("{0} Instance hashCode: {1 }",
This. GetType (). FullName,
This. GetHashCode ()
)
);
// Base. Render (writer );
Writer. AddAttribute (HtmlTextWriterAttribute. Id, this. ClientID );
Writer. AddAttribute (HtmlTextWriterAttribute. Bordercolor, "red ");
// The distance between the cell content and the cell border
Writer. addattriding (HtmlTextWriterAttribute. Cellpadding, "0 ");
// Distance between cells
Writer. addattriing (HtmlTextWriterAttribute. Cellspacing, "0 ");
Writer. RenderBeginTag (HtmlTextWriterTag. Table );
// Bar color
String color = string. Empty;
// Draw tr, td
For (int I = 0; I <Values. Count; I ++)
{
// Tr
Writer. RenderBeginTag (HtmlTextWriterTag. Tr );
// Td
Writer. RenderBeginTag (HtmlTextWriterTag. Td );
Writer. WriteEncodedText (Description [I]);
Writer. RenderEndTag ();
Writer. RenderBeginTag (HtmlTextWriterTag. Td );
// Writer. addattriattribute (HtmlTextWriterAttribute. Width, _ values [I]. ToString ());
Writer. AddStyleAttribute (HtmlTextWriterStyle. BorderColor, "blue ");
Writer. AddStyleAttribute (HtmlTextWriterStyle. BorderStyle, "solid ");
Writer. AddStyleAttribute (HtmlTextWriterStyle. BorderWidth, "1px ");
Color = (I % 2) = 0? "Red": "blue ");
Writer. AddStyleAttribute (HtmlTextWriterStyle. BackgroundColor, color );
Writer. AddStyleAttribute (HtmlTextWriterStyle. Width, Values [I]. ToString () + "px ");
Writer. RenderBeginTag (HtmlTextWriterTag. Div );
Writer. RenderEndTag ();
Writer. RenderEndTag ();
Writer. RenderEndTag ();
}
Writer. RenderEndTag ();
}
# Endregion
}
}
4.2 BarGraphControlWithViewStateProperty description:
4.2.1 This control works normally during form get
4.2.2 lost status during post
When Trace = 'true' is enabled on the page, the value of viewstate is displayed. The value of ViewState is definitely not complete.
_ ViewState during BarGraphControlWithViewStateProperty post
BarGraphControl post-return data
5 why is the control lost when BarGraphControlWithViewStateProperty is in post ???
5.1 compare the _ ViewState generated by BarGraphControl and BarGraphWithViewStateProperty at get.
5.1.1BarGraphControl get: _ ViewState generated on the page
<Input type = "hidden" name = "_ VIEWSTATE" id = "_ VIEWSTATE" value = "/wEPDwUKLTQ5NzYxMjc0Nw9kFgICAw9kFgICAQ8UKwAEZDLGAgABAAAA /////
WEAAAAAAAAABAEAAAB/Baidu
Bytes
Bytes
Bytes
Else //// aqaaaaaaaea
Bytes
Bytes
Bytes
Activities = "/>
5.1.2 _ ViewState generated on the page when BarGraphWithViewStateProperty get
<Input type = "hidden" name = "_ EVENTVALIDATION" id = "_ EVENTVALIDATION" value = "/wEWAgKTiu/aDAKM54rGBq/KxaTPszsZuaIb9spV87cnfmhD"/>
5.2 BarGraphControl event execution sequence
5.3 after tracking, we found that the BarGraphControlWithViewStateProperty value only has a value for max, and neither of the other two lists has a value. Will ViewState save only simple types and not complex types such as list <int>?
Protected void Page_Load (object sender, EventArgs e)
{
If (! IsPostBack)
{
SaveViewStateInfo ();
}
ShowViewStateInfo ();
}
Private void SaveViewStateInfo ()
{
This. ViewState ["max"] = 100;
This. ViewState ["list"] = new List <int> () {1, 2, 3 };
Dictionary <string, int> myDic =
New Dictionary <string, int> ()
{
{"Hb1", 100 },
};
This. ViewState ["dic"] = myDic;
}
Private void ShowViewStateInfo ()
{
StringBuilder sb = new StringBuilder ();
String info = string. Empty;
Info = string. Format ("Max: {0}", (int) this. ViewState ["max"]);
Sb. Append (info );
List <int> mylist = this. ViewState ["list"] as List <int>;
If (mylist! = Null)
{
Info = string. Format ("List. Count: {0}", mylist. Count );
Sb. Append (System. Environment. NewLine );
Sb. Append (info );
}
Dictionary <string, int> myDic = this. ViewState ["dic"] as Dictionary <string, int>;
If (myDic! = Null)
{
Info = string. Format ("Dictionary <string, int >:{ 0}", myDic. Count );
Sb. Append (System. Environment. NewLine );
Sb. Append (info );
}
Response. Write (sb. ToString ());
}
The above tests have been performed. Click the button and the ViewState storage List is correct.
5.4 StateBag TrackViewState mechanism. (ViewState is an instance of StateBag)
When a Post object is sent, the page stores the ViewState, and determines whether to persistently store the value in ViewState to _ ViewState. This is determined by StateBag. IsItemDirty ("key. If StateBag. isItemDirty ("key") is true, indicating that the data has been modified. In this case, the Control class calls the persistence method and writes the data corresponding to the key to the _ viewstate field after base64 encoding. If StateBag. IsItemDirty ("key") is false, Control will not add the data corresponding to the key to _ viewstate.
5.5 introduction to StateBag
Note:
1) StateBag is marked as Dirty only after the TrackViewState method is called and its key value is modified.
2) StateBag only traces and replaces the data directly with Dirty, but does not trace reference and modify the data.
5.5. 1 test code
StateBag myBag = new StateBag ();
MyBag ["key"] = new List <int> ();
(IStateManager) myBag). TrackViewState ();
List <int> mylist = myBag ["key"] as List <int>;
Mylist. Add (1 );
Console. WriteLine (myBag. IsItemDirty ("key "));
Output: False
MyBag ["key"] = new List <int> () {1, 2 };
Console. WriteLine (myBag. IsItemDirty ("key "));
Output: True
(I am sorry for the fact that the above document was previously written in excel and copied to writer, which makes the layout quite disgusting. You are welcome to correct the incorrect content in this document .)