Az ASP.NET-es alkalmazásainkban szerencsére erre is egyszerűen megvalósítható lehetőségünk van. Az alkalmazásunk amúgy is tárol minden kérésnél néhány a saját működéséhez szükséges adatot. Ezt észre sem vesszük, hacsak bele nem nézünk egy legenerált web oldal forráskódjába. Itt a Web Form-nál találunk egy __VIEWSTATE nevű rejtett mezőt:
<form name="Form1" method="post" action="WebForm1.aspx" id="Form1">
<input type="hidden" name="__VIEWSTATE" value="dDwtODM4MzkyNTM4O3Q8O2w8aTwxPjs"/>
Ez lesz a mező, mely kódolva tárolja a programunkhoz szükséges változók aktuális értékét minden egyes webes kérés esetén. Így ha egy újabb kérés indul a webes alkalmazásunk felé, akkor a __VIEWSTATE értékét felhasználhatjuk arra, hogy a legutóbbi kérésnél lévő értékeket visszatöltsük a szükséges változókba és a programunk ott folytathassa futását, ahol abbahagyta, legalábbis a változók szempontjából.
A __VIEWSTATE közvetlen kezelésére szerencsére nincs szükségünk, így csak a megfelelő függvények használatára kell összpontosítanunk a feladat megvalósításának érdekében.
Ez előtt azonban tegyünk egy kis kitérőt és készítsük el a bevezetőben említett új webes kontrolt, melyet a TestWebControlLibrary projektben valósítottunk meg.
A kontrolban létrehozunk három property-t (ColorR, ColorG, ColorB) a három színösszetevő tárolásához.
A kontrol a következő HTML kódot generálja:
<div style="width:100; height:100; background-color:#808080"> </div><div align=center>#808080</div>
Amint az látható a három szín property-ből származó színt a background-color stílusnak kell megadnunk. Ehhez szükségünk lesz egy olyan függvényre, mely a három színösszetevőből a #808080 sztringet előállítja. Ez a függvény lesz a HtmlRgb.
private string HtmlRgb(byte r, byte g, byte b)
{
return "#"+r.ToString("X2")+g.ToString("X2")+b.ToString("X2");
}
Ezek után jöhet a fenti HTML kód létrehozása a Render függvényben.
protected override void Render(HtmlTextWriter output)
{
RenderBeginTag(output);
string color = HtmlRgb(colorR, colorG, colorB);
output.Write("<div style=\"width:100; height:100; background-color:"+color+"\"> </div>");
output.Write("<div align=center>"+color+"</div>");
RenderEndTag(output);
}
Ha itt most megszakítjuk a kontrol fejlesztését és nem rendelkezünk arról, hogy a három szín property értéke megmaradjon két webes hívás között, akkor a bevezetőben leírt problémával találkozhatunk.
Ezt elkerülendő felül kell írnunk két függvényt: a SaveViewState akkor kerül meghívásra, amikor saját adatainkat eltárolhatjuk a __VIEWSTATE-be, míg a LoadViewState akkor fut, ha onnan betöltésre kerülnek az adatok.
Mentésnél meg kell hívnunk az ős osztály SaveViewState függvényét annak érdekében, hogy minden olyan adat tárolásra kerülhessen, melyekre a kontrolunk ős osztályainak szüksége van. E függvény visszatérési értékeként kapunk egy object típusú változót. Az eredménnyel nem kell foglalkoznunk csak tárolnunk azt. Ezt követően tárolhatjuk a mi adatainkat is tetszőleges számban. Számunkra most a három szín property értékének tárolására van szükségünk. Az egészet egy olyan tömbbe tároljuk, melynek elemei object típusúak. Mindig a tömb első elemébe kerül az ős osztály által visszaadott érték és tömb további elemeibe a saját értékeink. Végül a függvény visszatérési értékként az így felépített tömböt kapja.
protected override object SaveViewState()
{
object[] state = new object[4];
state[0] = base.SaveViewState();
state[1] = colorR;
state[2] = colorG;
state[3] = colorB;
return state;
}
A LoadViewState függvénynél történik a beolvasás. Itt is először az ős osztály LoadViewState függvényét kell meghívnunk, majd ezt követően olvashatjuk be saját adatainkat és tárolhatjuk a szükséges változókba.
protected override void LoadViewState(object savedState)
{
if (savedState != null)
{
object[] state = (object[])savedState;
if (state[0] != null)
{
base.LoadViewState(state[0]);
}
if (state[1] != null)
{
colorR = (byte)state[1];
}
if (state[2] != null)
{
colorG = (byte)state[2];
}
if (state[3] != null)
{
colorB = (byte)state[3];
}
}
}
Ezt a módszert használva kontrol bármilyen adata megőrizhető két webes kérés között, így az új kérésnél figyelembe lehet venni a legutóbbi kérésnél lévő adatokat, melyre a programunk helyes működése érdekében most szükségünk is van.
Végső próbaként tegyük meg a következőt: a WebForm1-en lévő WebCustomControl11 kontrolnál az EnableViewState property értékét állítsuk hamisra. Ezzel azt érjük el, hogy a kontrol LoadViewState és SaveViewState függvényei nem kerülnek meghívásra és ezzel a kontrol szín property-jeinek az értéke sem kerül megőrzésre. Futtassuk most így a programot és kattintsunk valamely színösszetevő növelését előidéző gombra többször egymás után. Jól megfigyelhető lesz, hogy ez a szín csak az első kattintásnál fog növekedni és tovább nem, mivel mindig az alapértéket növeljük amiatt, hogy az aktuális érték nem került megőrzésre.