
Mellékelt példa kipróbálásához szükséges egy RegistryView nevű virtuális könyvtár létrehozása, mely arra a könyvtárra mutat, amelybe másolta a példát. Ehhez legegyszerűbb út az adott mappa tulajdonság ablakában lévő Webmegosztás lapon található, ahol engedélyezzük a megosztást.
Készítünk tehát egy új Web Control-t, mely RegistryViewControl nevet kapja. Feladata az lesz, hogy megjelenítsen egy Windows regisztrációs adatbázis kulcsot és egy adott értéket. A kontrol megjelenítése két részre osztható: bal oldalt hierarchikusan jeleníti meg a kulcsot a megadott sztring alapján úgy, hogy az egyes szinteket a kulcsban megadott \ karakter mentén felbontja. A másik részén, a kontrol jobb oldalán egy táblázatot készít, melyben név, típus érték oszlopokban megjeleníti a megadott registry kulcson elérhető értéket és annak típusát.
A kontrol működéséhez négy új property-t kell létrehoznunk, melyek tárolják a megjelenítéshez szükséges értékeket.
A Path property-ben adhatjuk meg a megjelenítendő kulcsot. Az itt megadott szövegben lévő \ karakterek mentén fel lesz bontva a sztring több részre. Minden eleme ennek a sztringnek egy-egy szintet képez majd a megjelenítéskor.
public string Path
{
...
}
A megjelenítendő érték megnevezését a RegName property-ben adhatjuk meg.
public string RegName
{
...
}
Ennek típusát a RegType property-nél látható listából választhatjuk ki.
public RegValueType RegType
{
...
}
Végül az aktuális értéket a RegValue property-n keresztül adhatjuk meg megjelenítés céljából.
public string RegValue
{
...
}
A kontrol HTML kódjának generálása a Render függvényben történik. A kód generálást a RenderBeginTag függvény hívása kezdi, majd a RenderEndTag végzi. E két függvény biztosítja azt a szükséges HTML kódot az egyéb kódok körül, mely képessé teszi a kontrolunkat, hogy tetszőleges helyre pozícionálhassuk a web lapon belül.
protected override void Render(HtmlTextWriter output)
{
RenderBeginTag(output);
A Path property-ben lévő sztringet most fel kell bontanunk több sztringre a \ karakter mentén.
char[] c = {'\\'};
string[] items = path.Split(c);
Eredményképpen kapunk egy tömböt, mely sztringeket tartalmaz. Minden elem a megjelenítendő hierarchia egy-egy eleme lesz. Ennek megjelenítéséhez egy ciklussal végigmegyünk ezen a tömbön.
for (int i=0; i<items.Length; i++)
{
A megjelenítés folyamán három különböző képet kell majd használnunk attól függően, hogy a hierarchia kezdetén, végén, vagy éppen e kettő között vagyunk-e. Ettől függ a vízszintes eltolás mértéke is, melyet az l változóba tárolunk, míg a kép állomány nevének kezdőbetűje az img változóba kerül.
if (i==items.Length-1)
{
img = "b";
l = 4;
}
else
{
if (i==0)
{
img = "c";
l = 15;
}
else
{
img = "a";
l = 0;
}
}
Ezt követi a kép megjelenítése, melyet egy <IMG> HTML objektumra bízunk. A vízszintes pozícióját a Left property-jén keresztül adjuk meg, ezzel biztosítva az egyes hierarchia szintek eltolását.
output.Write("<img style=\"position:absolute; left="+(i*18+l).ToString()+"\" src=\""+img+".gif\">");
E képet követheti a hozzátartozó szöveg megjelenítése, melyet szintén el kell tolnunk vízszintes irányban, hogy a kép mellé kerüljön.
output.Write("<span style=\"position:relative; top=2; left="+(i*18+38).ToString()+"\">"+items[i]+"</span><br>");
}
A ciklus végére a szükséges hierarchia elő is áll. Most következhet a hierarchia mellett megjelenő táblázat, melyben a megadott értéknek kell megjelennie. Ezt a táblázatot szintén el kell tolnunk vízszintes irányban, olyan mértékben, hogy az ne lógjon bele a hierarchiába semmi esetre sem. Itt felmerül viszont egy probléma: mekkora is legyen az eltolás mértéke? E kérdésre a választ a GetMaxWidth függvény adja meg, mely figyelembe veszi, hogy a Path property-ben megadott sztring az adott betűtípussal és mérettel mekkora helyet fog elfoglalni a képernyőn. Ehhez az értékhez még hozzáadunk 20 pixelt, hogy a két grafikai objektum között legyen egy kis üres hely is.
output.Write("<table width=\"100%\" cellspacing=4 cellpadding=0 style=\"position:absolute; left="+(GetMaxWidth()+20).ToString()+"; top=0\">");
A táblázat legenerálása a továbbiakban már egyszerű: létrehozunk két sort és ezekben négy-négy oszlopot. Az első sorba az oszlopok megnevezése kerül, a másodikba a hozzájuk tartozó érték.
...
RenderEndTag(output);
}
Végül nézzük miként működik a GetMaxWidth függvény, mely képes meghatározni a hierarchia által elfoglalt terület szélességét pixelben, így pontosan e mellé igazíthatjuk a táblázatunkat. A probléma összetett, mert azon kívül, hogy a hierarchia elemei egymáshoz képest minden szinten egyre jobban eltolódnak, még az is gondot okozhat, hogy nem is a legutolsó sora végződik a legjobban jobb oldalt. Ez akkor állhat elő, ha a hierarchia szinten előrébb lévő szöveg szélessége hosszabb mint az azt követő. Biztos tehát, hogy az összes sort végig kell vizsgálnunk és a legszélesebb helyet elfoglaló sort kell figyelembe vennünk a teljes hierarchia szélességének meghatározásakor.
Szükségünk lesz tehát arra, hogy egy-egy sztring szélességét programból meghatározhassuk egy adott betűtípus és méret mellett. Ehhez a Grahpics osztály MeasureString függvénye fog segíteni. Mivel itt webes alkalmazásról van szó, így nehézségbe ütközünk akkor is, ha egy Graphics osztályt megpróbálunk létrehozni.
Ennek leküzdésére azt a trükköt alkalmazzuk, hogy egy olyan Graphics osztályt hozunk létre, mely a teljes képernyőre vonatkozik, így képesek leszünk a szükséges számítást elvégeztetni. Ehhez azonban egy Windows függvény hívására is szükségünk lesz, mely képes egy HDC azonosító megszerzésére, melyet felhasználva a Graphics osztály létrehozható. Ez a függvény a GetDC lesz, melynek nulla értéket adva paraméterként a képernyőre vonatkozó azonosítót kapjuk vissza, melyet már felhasználhatunk a Graphics osztály FromHdc függvényében.
private int GetMaxWidth()
{
int dc = Win32.GetDC(0);
Graphics graphics = Graphics.FromHdc((IntPtr)dc);
Ezzel a Graphics osztályunk már adott, most már csak vizsgálni kell a sztringek hosszát, amihez ismét felbontjuk a Path property értékét a \ karakter mentén.
char[] c = {'\\'};
string[] items = path.Split(c);
Ezt követően jöhet a ciklus, mely vizsgálja az összes sztring hosszát és kiválasztja ezek közül a legnagyobbat.
for (int i=0; i<items.Length; i++)
{
A MeasureString függvény hívásával lekérdezzük az adott sztring méretét Veradana 8-as méretű betűtípus esetén, mivel a megjelenítés is ezzel történik a web oldalon.
size = graphics.MeasureString(items[i], new Font("Verdana", 8));
Kiszámítjuk az adott sztring aktuális eltolásának mértékét a hierarchia miatt. Majd ellenőrizzük, hogy a sztring jobb oldala a web oldalon hol fog végződni, mert ez adja meg a teljes hierarchia szélességét. Ha ez nagyobb mint az eddig talált és a max változóban tárolt szélesség, akkor újra tároljuk ezt az értéket a max-ba, mint az eddig megtalált legnagyobb szélességet.
left = i*18+38;
if (left+size.Width > max)
{
max = left+(int)size.Width;
}
}
A ciklus végén felszabadítjuk a GetDC által lefoglalt erőforrásokat, majd visszaadjuk a max aktuális értékét, mely a megjelenítendő hierarchia szélességét adja pixelben, Verdana 8-as méretű font esetén.
Win32.ReleaseDC(0, dc);
return max;
}