Практика: Templated User Control
Всі знають, що таке User Control. В свій час мені дуже потрібно було зробити контрол, дизайн якого можна було б потім змінювати під свої потреби без рекомпіляції і надмірних хвилювань. Так як це зроблено в UpdateProgress, TabControl і інших контролах. Саме для таких цілей існує templated user control, про який я хочу розповісти. На перший погляд потрібно зробити багато дій, проте зробивши один раз, в подальшому проблем бути не повинно.
ТЗ: розробити templated user control для виведення інформації про компанію, а саме company name i company owner. Дати можливість користувачеві самому вибрати дизайн для відображення.
Створюємо новий веб-сайт і додаємо новий елемент - user control з назвою TemplatedCompanyInfo.ascx.
Додаємо новий клас CompanyInfoContainer, який буде контейнером для нашого контролу. Робимо його нащадком від класу Control і інтерфейсу INamingContainer, створюємо два проперті - CompanyName і CompanyOwner, створюємо конструктор:
public class CompanyInfoContainer : Control, INamingContainer { public string CompanyName {get; set;} public string CompanyOwner { get; set; }
public CompanyInfoContainer(string companyName, string companyOwner) { this.CompanyName = companyName; this.CompanyOwner = companyOwner; }
}
В TemplatedCompanyInfo створюємо проперті для нашого темплейту, наприклад CompanyInfoTemplate типу ITemplate. У нього обов'язково мають бути задані два атрибути: PersistenceMode і TemplateContainer. Виглядає це так:
[PersistenceMode(PersistenceMode.InnerProperty)] [TemplateContainer(typeof(CompanyInfoContainer))] public ITemplate CompanyInfoTemplate { get; set; }
Додаємо відповідні проперті (такі як в темплейті, хоча назви можуть відрізнятися):
public string CompanyName { get; set; } public string CompanyOwner { get; set; }
Необхідно додати на сторінку ascx PlaceHolder, де буде відображатися дані:
Основна частина - ініціалізація темплейту. Її можна робити в OnInit:
protected override void OnInit(EventArgs e) {
// Очищаємо всі контроли в нашому PlaceHolder1
PlaceHolder1.Controls.Clear();
// Перевіряємо, чи користувач задав шаблон, якщо ні - виводимо повідомлення "No template defined!"
if (CompanyInfoTemplate == null) {
PlaceHolder1.Controls.Add(new LiteralControl("No template defined!")); return; }
// Ініціалізуємо контейнер нашими даними
CompanyInfoContainer container = new CompanyInfoContainer(this.CompanyName, this.CompanyOwner);
// Зв'язуємо наш темплейт (проперті) і темплейт-контрол
CompanyInfoTemplate.InstantiateIn(container);
// Додаємо все в PlaceHolder1
PlaceHolder1.Controls.Add(container);
base.OnInit(e); }
Додаємо контрол на сторінку (Default.aspx), задаємо темплейт і дані:
<%@ Register src="TemplatedCompanyInfo.ascx" tagname="TemplatedCompanyInfo" tagprefix="uc2" %>
Company Owner:
Обов'язково робимо DataBind() для сторінки:
protected void Page_Load(object sender, EventArgs e) { DataBind(); }
Дивимось що отримали:
Змінюючи код в файлі aspx дизайн буде змінюватися автоматично. Якщо користувач не задасть темплейта - то буде показано надпис "No template defined".
Все!