Jedna z věcí, která nejen mne zaujala na přednášce o Visual Studiu
2008, byl LayoutTemplate u nového kontrolu
asp:ListView. Jak na jeho implementaci se pokusí nastínit
tento člán.
Šablonované ovládací prvky jsou v ASP.NET celkem běžnou věcí a
jejich výskyt asi nikoho nepřekvapí. Celkem běžná je také praktika
HeaderTemplate a FooterTemplate jejichž obsah se
renderuje na začátku/konci. Pokud chcete mít třeba render obalený v
div značce, dojde k tzv. křížení značek, což je v XML
nepěkná praktika, a některé editory na tom selžou. Kód by mohl vypadat
následovně:
...
<HeaderTemplate><div></HeaderTemplate>
<FooterTemplate></div></FooterTemplate>
...
Oproti tomu LayoutTemplate přichází s tím, že šablona
Headeru i Footeru je v jednom. Asi následovně:
...
<LayoutTemplate>
<div id="layoutContainer" runat="server"></div>
</LayoutTemplate>
...
Pěkné, že? Někdo se možná zalekne runat="server", že by
to třeba mohlo renderovat něco jinýho než by chtěl. Nebude ;)
Jak to funguje?
Lepší bude si to celé vysvětlit na ukázce kódu. Naimplementujeme si
vlastní LayoutTemplateable control. Začneme tím, že si vytvoříme
rozhranní ILayoutTemplateable.
public interface ILayoutTemplateable {
string LayoutContainerId { get; set; }
[TemplateContainer(typeof(Control))]
ITemplate LayoutTemplate { get; set; }
}
Dalším krokem bude TemplatingHelper, který nám pomůže
s instancováním šablon a vytvořením layout kontejneru.
public static class TemplatingHelper {
public static Control CreateLayoutContainer(Control parent, ILayoutTemplateable item) {
Control container = new Control();
Instantiate(container, item.LayoutTemplate, parent);
return container.FindControl(item.LayoutContainerId);
}
public static void Instantiate(Control container, ITemplate template, Control parent) {
if (template == null || parent == null)
return;
if (container == null)
container = new Control();
template.InstantiateIn(container);
parent.Controls.Add(container);
}
}
No a na konec ukázka užití:
public class TemplatedControl : Control, ILayoutTemplateable {
...
public override void CreateChildControls() {
Controls.Clear();
// vytvorime layoutContainer
Control layoutContainer = TemplatingHelper.CreateLayoutContainer(this, this);
// vytvorime polozky
foreach (string item in collection) {
TemplatingHelper.Instantiate(new StringContainer(item), ItemTemplate, layoutContainer);
}
}
}
Doufám, že to funguje, páč jsem si to teď nějak vycucal
z prstů… Ale principielně, by to mělo fungovat. Tak už jsem se
dostal k implementaci a kupodivu to celé funguje. :)
Komentáře
Michal
21.23 - 14. června 2007 | #
Aleš Roubíček
22.07 - 14. června 2007 | #
Discogio
21.34 - 15. června 2007 | #
Aleš Roubíček
09.33 - 16. června 2007 | #
Discogio
14.13 - 16. června 2007 | #
Místo pro tvůj názor