
Mellékelt példa megnyitása előtt szükséges egy WebControlDesign nevű virtuális könyvtár létrehozása, mely a példa könyvtárára mutat. Ehhez nyissa meg a mellékelt mappa Tulajdonság ablakát és itt a Webmegosztás lapon engedélyezze a mappa megosztását olvasási és parancsfájlok futtatási jogával.
A komponens funkciói
Az elkészítendő komponens funkcióját tekintve nem számít különlegesnek, hiszen most nem is ez a fontos. A komponens egy olyan DataList kontrol, mely az alkalmazás futásakor egy link-listát jelenít meg a címet tartalmazó fejléccel és egy záró utalást tartalmazó lábrésszel, melyek tetszőleges Web-helyen fellelhető információkra mutathatnak. A megjelenítendő információkat a komponens most egy XML-állományból olvassa ki, ez azonban lehet tetszőleges adatbázisban elhelyezett információ vagy egy másik weboldal is.
A megjelenített információ formázása stílusosztályok alapján történik, melyek egy wcd.css nevű állományban találhatók az alkalmazás főmappájában. A kontrol futása előtt értéket kell adnunk a property-jeinek. Ezek lokális változók értékeit állítják, melyek a követezők:
A lista címét tartalmazó változó:
private string title = "A SoftwareOnline legfrissebb cikkei";
A formázási stílusosztály nevét tartalmazó változó:
private string css = "wcd";
A megjelenített információt tartalmazó XML-állomány nevét tartalmazó változó:
private string source = "Articles.xml";
A változók a következő property-ken keresztül kapnak értéket
Title property
[Bindable(true),
Category("WebControlDesign"),
Description("Megadható a megjelenítendő győjtemény főcíme")]
public string Title
{
get
{
return title;
}
set
{
title = value;
}
}
LinkCss property
[Bindable(true),
Description("A linkek és a fejlécszöveg stílusa"),
Category("WebControlDesign")]
public string LinkCss
{
get
{
return css;
}
set
{
css = value;
}
}
XMLSource property
[Bindable(true),
Description("A cikkek adatait tartalmazó XML állomány neve"),
Category("WebControlDesign")]
public string XMLSource
{
get
{
return source;
}
set
{
source = value;
}
}
A komponens a GetArticles nevű függvényében végzi az adatforrás kiolvasását. A függvény egy DataTable osztályú objektumot ad vissza, mely adatforrása lesz a kontrolnak.
private DataTable GetArticles()
{
A következő lépésben betöltjük a megfelelő adatszerkezetbe az XML-állomány tartalmát. Bármilyen hiba esetén egy ErrorForm.aspx nevű oldal töltődik be, melyen szerepel a megadott állomány elérési útja, valamint a hiba lehetséges oka. A feltöltött adatszerkezetet elmentjük a Cache objektumba későbbi felhasználás céljából.
string XMLsrc = Context.Server.MapPath(source);
DataTable dt = new DataTable();
DataSet ds = new DataSet();
try
{
ds.ReadXml(XMLsrc,XmlReadMode.ReadSchema);
dt = ds.Tables[0];
}
catch(Exception e)
{
HttpContext.Current.Response.Redirect("ErrorForm.aspx?src=" + XMLsrc);
}
HttpContext.Current.Cache.Insert("data",ds);
return dt;
}
A komponens inicializációját az OnLoad függvénye végzi el, melyben megadjuk a formázó „template-objektumokat”, valamint beállítjuk a kontrol DataSource property-jét.
protected override void OnLoad(EventArgs e)
{
base.HeaderTemplate = new HeaderFooter(GetHeaderText(title),css);
base.ItemTemplate = new HyperLinks(css);
base.FooterTemplate = new HeaderFooter(foot);
base.DataSource = GetArticles();
base.DataBind();
}
A fej- és lábléc formázásáért felelős osztály
A kontrol HeaderFooter osztálya végzi el a formázást. Konstruktoraiban megadjuk, hogy milyen szöveget, milyen stílusosztállyal akarunk formázni. Az InstantiateIn metódus megvalósításával tulajdonképpen egy Label osztályú objektumot formázunk, és ezt adjuk gyermekkontrolként a komponensünkhöz.
public void InstantiateIn(Control container)
{
Label l = new Label();
l.Text = text;
if(css != null)
{
l.CssClass = css;
}
container.Controls.Add(l);
}
A linklista formázásáért felelős osztály
A kontrol HyperLinks osztályában megírt függvényekkel érjük el azt, hogy az egyes linkek a megfelelő szöveget mutassák, valamint hogy a linkre kattintva egy másik oldalra navigálja a felhasználót. A linkek is gyermekobjektumai lesznek a kontrolnak:
public void InstantiateIn(Control container)
{
HyperLink hyperlink = new HyperLink();
hyperlink.Target = "_blank";
if(css != null)
{
hyperlink.CssClass = css;
}
hyperlink.DataBinding += new EventHandler(this.LinkBind);
container.Controls.Add(hyperlink);
container.Controls.Add(new LiteralControl("<br />"));
}
A linkek adatforrásként a kontrol adatforrását használják, így a DataBinding esemény bekövetkezésekor onnan töltik fel Text és NavigateUrl property-jeiket. Ehhez kell írnunk egy kezelőfüggvényt, mely a LinkBind nevet viseli:
public void LinkBind(object sender, EventArgs e)
{
HyperLink hl = (HyperLink) sender;
DataListItem container = (DataListItem) hl.NamingContainer;
hl.NavigateUrl = (DataBinder.Eval(container.DataItem, "Url")).ToString();
hl.Text = (DataBinder.Eval(container.DataItem, "Title")).ToString();
}
A linkekhez most egy oldal tartozik, mely megjeleníti az adott cikk adatait. Ez az oldal természetesen lehetne egy valódi megjelenítő oldal is.
A szerkesztési idejű megjelenítésért felelős osztály
A kontrolok weblapra helyezésükkor, azaz már fejlesztési időben is rendelkeznek HTML kóddal. Ennek a kódnak a megadásával, illetve módosításával érhetjük el, hogy kontrolunk egyedi megjelenítésű legyen már futás előtt. Ehhez a System.Web.UI.Design névtér ControlDesigner osztályát használhatjuk fel. Az osztály két függvényének felülírásával megadhatjuk a megjelenítésre vonatkozó információkat. A komponensünk WebControlDesignDesigner osztályát származtattuk a fenti osztályból, hogy hozzáférjünk a függvényekhez. Az Initialize metódusban példányosítjuk a kontrolunkat, majd inicializáljuk azt.
public override void Initialize(IComponent component)
{
newcontrol = (WebControlDesignControl)component;
base.Initialize(component);
}
A GetDesignTimeHtml függvényben pedig megadhatjuk, hogy milyen legyen ez a megjelenítés. Első lépés, hogy a függvényben létrehozunk egy StringWriter és egy HtmlTextWriter osztályú objektumot, melyek tartalmazzák, majd a kimenetre írják a HTML-kódot. A függvény visszatérési értéke egy string, mely magát a kódot tartalmazza.
public override string GetDesignTimeHtml()
{
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
A következőkben megadjuk, hogy kontrolunk szerkesztési időben egy táblázat legyen, amely sorai a beállított property-k értékeit tartalmazzák.
Table t = new Table();
t.BorderColor = ColorTranslator.FromHtml("#FFCC00");
t.BackColor = ColorTranslator.FromHtml("#FFCC00");
t.BorderStyle = BorderStyle.Solid;
t.Rows.Add(AddRow("Cikklink-lista megjelenítéséhez szükséges paraméterek"));
t.Rows.Add(AddRow("Title", newcontrol.Title));
t.Rows.Add(AddRow("LinkCss", newcontrol.LinkCss));
t.Rows.Add(AddRow("XMLSource", newcontrol.XMLSource));
t.RenderControl(htw);
return sw.ToString();
}
A függvényt a keretprogram hívja meg, közvetlenül nem hívható. A tábla feltöltéséhez felhasznált AddRow függvények egy-egy sorral térnek vissza, mely már értékeket tartalmaz. Az egyik megvalósítás, mely csak egy string-et vár paraméterként a cím sorának beállítását szolgálja.
Felhasználása előtt a kontrolt fel kell tenni a ToolBox-ra a szokásos módon: kattintsunk a ToolBox valamely lapján az egér jobb gombjával, majd a megjelenő menüből válasszuk ki a Customize ToolBox pontot, a megjelenő ablakban a .NET Frameworks Components fület. A Browse gombbal keressük elő az imént létrehozott .DLL-t.