Програмне створення шаблонів серверних елементів управління (исходники), Різне, Програмування, статті

Анотація


Демонструється, як програмно створювати шаблони для серверних ASP.NET-елементів управління Repeater, DataList і DataGrid; Дані приклади на Visual Basic. NET і Visual C #. NET.

Зміст


Стаття поділена на розділи, в кожному з яких демонструються все більш складні способи створення шаблонів (templates). Наприклад, з першого розділу ви дізнаєтеся, як створювати в коді найпростіші наблони. У наступних розділах цей шаблон ускладнюється, до нього додається нова функціональність. До кінця статті ви навчитеся створювати повнофункціональний шаблон, здатний до зв’язування з даними (data binding).


Вимоги


Ця стаття передбачає, що ви знаєте, як створювати сторінки на основі Web-форм (Web Forms) і серверних елементів керування ASP.NET. Крім того, передбачається, що ви хоча б експериментували в Web Forms Designer з створенням шаблонів для ASP.NET-елементів Repeater або DataList. Базову інформацію про шаблони см. за посиланням Web Server Controls Templates.

Нарешті, передбачається, що ви вмієте пов’язувати елементи управління на сторінках – Web-формах з даними. Базову інформацію про зв’язуванні з даними см. в документації Microsoft ® Visual Studio ®. NET (Web Forms Data Binding).

Введення


Серверні елементи управління ASP.NET Repeater, DataList і DataGrid розраховані на зв’язування з даними (data binding). Вони генерують один елемент (item) (наприклад, рядок) для кожного елемента (element) у зв’язаному з ними джерелі даних. Розмітка даних визначається шаблонами. Шаблон – це контейнер для інших елементів управління, не має власного користувальницького інтерфейсу (UI). Щоб виводити інформацію, до шаблону потрібно додати елементи управління і налаштувати їх властивості, що визначають зовнішній вигляд (display properties) (зазвичай через зв’язування з даними). Під час своєї роботи елемент управління перебирає елементи в джерелі даних і для кожного з них створює свій елемент, що з’єднує елементи управління в шаблоні з інформацією в елементі даних.

Елементи управління Repeater і DataList дозволяють виводити результат в більш вільній формі: елементами можуть бути рядки таблиці, пункти маркірованого списку, елементи списку, розділені комами, або що завгодно ще. Елемент управління DataGrid використовує зумовлений формат – сітку (grid). Кожен елемент даних відповідає рядку в сітці. При відображенні елемента керування кожен елемент показується як рядок таблиці.

Визначення шаблонів


Якщо ви працюєте з елементами управління Repeater, DataList або DataGrid на сторінці Web Forms, створити шаблон на етапі розробки нескладно. DataList підтримує вікно редагування у стилі WYSIWYG. Що стосується Repeater, Його шаблони створюються у вікні перегляду HTML (HTML view) у вигляді спеціальних елементів, вкладених в елемент керування. Для створення нового шаблонного стовпця в елементі управління DataGrid скористайтеся вікном Properties.

Але це передбачає, що шаблони створюються на етапі розробки. З різних причин іноді на цьому етапі не відомо, які шаблони знадобляться або який в них потрібен текст і елементи керування. В цьому випадку треба створювати шаблони “на льоту”. А для цього слід зрозуміти основні принципи створення класів і зв’язування з даними в Web Forms. У цьому вам і допоможе ця стаття.

Примітка. Крім того, можна створювати шаблони у вигляді користувача елементів управління Web Forms і динамічно пов’язувати їх з елементами управління на сторінці. Більш детальну інформацію див Creating a Templated User Control в документації. NET Framework SDK.

Базові відомості про програмне створенні шаблонів


Для початку розглянемо, як створити найпростіший шаблон в коді. Для цього потрібно виконати наступні вирази:






” Visual Basic
Repeater1.ItemTemplate = New MyTemplate()
// C#
Repeater1.ItemTemplate = new MyTemplate();

Як бачите, тут створюється екземпляр класу MyTemplate. Звідки береться цей клас шаблону? Ви самі його і створюєте.

Примітка. Шаблони для DataGrid створюються в коді трохи інакше, тому що в цьому випадку ви створюєте стовпець. Додаткові відомості ви знайдете в кінці статті. Однак більшість відомостей про елементах управління DataList і Repeater відносяться і до DataGrid.

Базовий клас шаблону


Клас шаблону відносно простий. Як мінімум, у ньому потрібно:


Звичайно, сенс шаблону – у висновку тексту та елементів управління для кожного елемента в джерелі даних. Це робиться в методі класу InstantiateIn, Саме там створюється UI шаблону.

Зазвичай сценарій роботи з цим методом такий: ви створюєте новий елемент управління, налаштовуєте необхідні властивості, а потім додаєте його в набір (cillection) Controls батьківського елемента. Статичний текст безпосередньо додати в цей набір можна, але ви можете створити елементи управління Literal або LiteralControl, Налаштувати їх властивості Text і додати їх до батьківського набору. Метод InstantiateIn передає посилання на батьківський елемент управління (елемент управління Repeater, DataList або DataGrid), Що спрощує останній крок.

Нижче наведено повний клас шаблону, що виводить статичний текст (“Item number:”) і лічильник. Лічильник зберігається в поділюваної або статичної (в залежності від мови програмування) змінної класу itemcount і збільшується на 1 при кожному створенні нового елемента.






” Visual Basic
Public Class MyTemplate
Implements ITemplate
Shared itemcount As Integer = 0
Sub InstantiateIn(ByVal container As Control) _
Implements ITemplate.InstantiateIn
Dim lc As New Literal()
lc.Text = “Item number: ” & itemcount.ToString & “<BR>”
itemcount += 1
container.Controls.Add(lc)
End Sub
End Class
// C#
private class MyTemplate : ITemplate
{
static int itemcount;
public void InstantiateIn(System.Web.UI.Control container)
{
Literal lc = new Literal();
lc.Text = “Item number: ” + itemcount.ToString() + “<BR>”;
itemcount += 1;
container.Controls.Add(lc);
}
}

Тестування класу шаблону


Щоб подивитися, як працює наш клас, протестуйте його з елементом управління Repeater. Почніть зі створення нової сторінки на основі Web Forms і виконайте такі дії.


  1. Додайте елемент управління Repeater.
  2. Додайте об’єкт з’єднання з даними і адаптер даних. Для цього тесту тип даних не важливий.
  3. Створіть набір даних (dataset), схема якого збігається з SQL-запитом у створеному адаптері даних. Там зберігаються дані, що виводяться в елементі управління.

    Рада. Якщо ви користуєтеся Visual Studio, перетягніть адаптер даних на сторінку і створіть з’єднання за допомогою майстра. Потім викличте команду Generate Dataset з меню Data і створіть типізований набір даних.


  4. Дайте властивості DataSource елемента управління Repeater створений набір даних і запишіть у властивість DataMember ім’я таблиці в наборі даних.

Тепер ви готові до створення класу шаблону. Виконайте наступні дії.


  1. Скопіюйте останній приклад, наведений вище, і вставте його в код сторінки.

    Сторінка із вставленим класом виглядає приблизно так (вставлений код виділений):






    ” Visual Basic
    Public Class WebForm1
    Inherits System.Web.UI.Page
    “Інші оператори спадкування
    Private Class MyTemplate
    Implements ITemplate
    Dim itemcount As Integer = 0
    Sub InstantiateIn(ByVal container As Control) _
    Implements ITemplate.InstantiateIn
    Dim lc As New Literal()
    lc.Text = “Item number: ” & itemcount.ToString & “<BR>”
    itemcount += 1
    container.Controls.Add(lc)
    End Sub
    End Class
    “І т. д.
    // C#
    using System;
    using System.Collections;
    / / Інші простору імен
    namespace myproject
    {
    public class WebForm1 : System.Web.UI.Page
    {
    protected System.Data.SqlClient.SqlDataAdapter sqlDataAdapter1;
    / / Інші оголошення
    public class MyTemplate : ITemplate
    {
    int itemcount;
    public void InstantiateIn(System.Web.UI.Control container)
    {
    Literal lc = new Literal();
    lc.Text = “Item number: ” + itemcount.ToString() + “<BR>”;
    itemcount += 1;
    container.Controls.Add(lc);
    }
    }
    / / І т. д.


  2. Додайте до обробникові Page_Load код, що створює екземпляр класу шаблону, і надайте його властивості ItemTemplate елемента управління Repeater.
  3. Нарешті, в обробнику Page_Load заповніть набір даних і викличте метод DataBind елемента управління Repeater.

    Після цього обробник Page_Load буде виглядати приблизно так (код, доданий на етапах 2 і 3, виділений):






    ” Visual Basic
    Private Sub Page_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
    Repeater1.ItemTemplate = New MyTemplate()
    SqlDataAdapter1.Fill(DataSet11)
    Repeater1.DataBind()
    End Sub
    // C#
    private void Page_Load(object sender, System.EventArgs e)
    {
    Repeater1.ItemTemplate = new MyTemplate();
    sqlDataAdapter1.Fill(dataSet11);
    Repeater1.DataBind();
    }


  4. Запустите сторінку.

    Ви побачите список, кожному рядку якого відповідає один елемент із джерела даних.



Додавання шаблонів інших типів


Вищенаведені приклади демонструють роботу з єдиним шаблоном, а саме: з шаблоном елементу (item template). З цього розділу ви дізнаєтеся, як створювати більш складну версію класу шаблону, що дозволяє вказувати шаблон заголовка (header template), шаблон нижнього колонтитула (footer template), шаблон змінного елементу (alternating item template) (для Repeater і DataList) І т. д.

По-перше, можна створити окремий клас шаблону для кожного типу шаблону чи базовий клас шаблону і похідні від нього класи для різних типів шаблонів. Це може виявитися практичним, якщо шаблони дуже складні або сильно відрізняються один від одного.

З іншого боку, можна скористатися одним класом для всіх елементів і вказувати, який тип створюваного шаблона. Для цього класу слід передати відповідне значення. Насправді, підійдуть значення з перерахування ListItemType, Вже визначеного для типів шаблонів в елементах управління Repeater, DataList і DataGrid.

Наведений нижче приклад – вдосконалена версія попереднього коду. Тепер клас містить явний конструктор, який приймає рядок, що визначає тип шаблону. Для з’ясування типу створюваного шаблону в методі InstantiateIn застосовується оператор Select Case або switch в залежності від мови програмування. Щоб показати переваги створення шаблонів різного типу, в прикладі створюється таблиця з різним кольором фону для шаблону змінного елементу (alternating item template).






” Visual Basic
Private Class MyTemplate
Implements ITemplate
Shared itemcount As Integer = 0
Dim TemplateType As ListItemType
Sub New(ByVal type As ListItemType)
TemplateType = type
End Sub
Sub InstantiateIn(ByVal container As Control) _
Implements ITemplate.InstantiateIn
Dim lc As New Literal()
Select Case TemplateType
Case ListItemType.Header
lc.Text = “<TABLE class=borderall><TR><TH>Items</TH></TR>”
Case ListItemType.Item
lc.Text = “<TR><TD>Item number: ” & itemcount.ToString _
& “</TD></TR>”
Case ListItemType.AlternatingItem
lc.Text = “<TR><TD bgcolor=lightblue>Item number: ” _
& itemcount.ToString & “</TD></TR>”
Case ListItemType.Footer
lc.Text = “</TABLE>”
End Select
container.Controls.Add(lc)
itemcount += 1
End Sub
End Class
// C#
public class MyTemplate : ITemplate
{
static int itemcount = 0;
ListItemType templateType;
public MyTemplate(ListItemType type)
{
templateType = type;
}
public void InstantiateIn(System.Web.UI.Control container)
{
Literal lc = new Literal();
switch( templateType )
{
case ListItemType.Header:
lc.Text = “<TABLE class=borderall><TR><TH>Items</TH></TR>”;
break;
case ListItemType.Item:
lc.Text = “<TR><TD>Item number: ” + itemcount.ToString() +
“</TD></TR>”;
break;
case ListItemType.AlternatingItem:
lc.Text = “<TR><TD bgcolor=lightblue>Item number: ” +
itemcount.ToString() + “</TD></TR>”;
break;
case ListItemType.Footer:
lc.Text = “</TABLE>”;
break;
}
container.Controls.Add(lc);
itemcount += 1;
}
}

Для створення різних шаблонів використовується приблизно такий код:






” Visual Basic
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Repeater1.HeaderTemplate = New MyTemplate(ListItemType.Header)
Repeater1.ItemTemplate = New MyTemplate(ListItemType.Item)
Repeater1.AlternatingItemTemplate = _
New MyTemplate(ListItemType.AlternatingItem)
Repeater1.FooterTemplate = New MyTemplate(ListItemType.Footer)
SqlDataAdapter1.Fill(DataSet11)
Repeater1.DataBind()
End Sub
// C#
private void Page_Load(object sender, System.EventArgs e)
{
Repeater1.HeaderTemplate = new MyTemplate(ListItemType.Header);
Repeater1.ItemTemplate = new MyTemplate(ListItemType.Item);
Repeater1.AlternatingItemTemplate =
new MyTemplate(ListItemType.AlternatingItem);
Repeater1.FooterTemplate = new MyTemplate(ListItemType.Footer);
sqlDataAdapter1.Fill(dataSet11);
Repeater1.DataBind();
}


Додавання в шаблон підтримки зв’язування з даними


Зараз наш клас шаблону здатний виводити тільки статичні дані. У цьому розділі ми доповнимо його підтримкою включення даних з джерела.

Звертатися до даних з класу шаблону можна по-різному, в залежності від способу створення класу. По-хорошому архітектура сторінки сама повинна реалізувати зв’язування з даними. Додаючи елементи керування до шаблону, ви додаєте і обробник події DataBinding. Воно викликається після того, як шаблон створить всі свої елементи управління.

Примітка. Можливо, ви вважаєте, що вираз зв’язування з даними можна вбудувати просто у вигляді рядка при створенні елементів управління в шаблоні – точно так само, як і при визначенні шаблонів на етапі розробки. Але нічого не вийде: виявляється, вирази зв’язування з даними перетворюються в код при обробці сторінки, тобто до створення шаблону.

В обробнику події DataBinding ви можете керувати вмістом елемента управління. Зазвичай (але не обов’язково) дані звідкись завантажуються і записуються у властивість Text елемента управління.

Примітка. Базову інформацію про зв’язуванні даних на сторінках Web Forms см. в документації Visual Studio. NET за посиланням Web Forms Data Binding.

Зв’язування обробника подій з елементами управління


Почніть зі зв’язування обробника подій з створюваними в шаблоні елементами управління. У наведеному нижче фрагменті елемент управління в шаблоні зв’язується з обробником TemplateControl_DataBinding. (Код самого обробника ви додасте пізніше.)






” Visual Basic
Case ListItemType.Item
lc.Text = “<TR><TD>”
AddHandler lc.DataBinding, AddressOf TemplateControl_DataBinding
// C#
case ListItemType.Item:
lc.Text = “<TR><TD>”;
lc.DataBinding += new EventHandler(TemplateControl_DataBinding);
break;

Примітка. Додаткову інформацію про динамічний додаванні обробників подій см. AddHandler and RemoveHandler (Для Visual Basic) і Events Tutorial (Для Visual C #) в документації Visual Studio. NET.

Зверніть увагу, що в цьому прикладі текст, який додається до строковому властивості Text елемента управління, відрізняється від тексту в попередньому. Він містить тільки початок рядка таблиці і осередки для шаблону елемента. Осередок і рядок ми закінчимо в обробнику події зв’язування з даними.

Створення обробника події


Тепер нам потрібен обробник, що викликається при зв’язуванні елемента управління з даними. Оброблювач є частиною класу шаблону і нічим не відрізняється від інших методів класу (на кшталт InstantiateIn).

Сигнатура обробника показана в наступному прикладі. Ім’я обробника має збігатися з ім’ям, зазначеному при зв’язуванні з обробником.






” Visual Basic
Private Sub TemplateControl_DataBinding(ByVal sender As Object, _
ByVal e As System.EventArgs)
// C#
private void TemplateControl_DataBinding(object sender,
System.EventArgs e)

При виклику методу ви передаєте в аргументі sender посилання на елемент управління, тому можете налаштовувати його властивості. Так як цей аргумент має тип object, його треба привести до елементу управління правильного типу (у нашому прикладі – до Literal).

Як отримати доступ до даних? Для кожного елемента в джерелі даних Repeater, DataList або DataGrid створює один елемент, вміст якого грунтується на шаблоні. Кожен такий елемент містить властивість DataItem, Що забезпечує доступ до даних для цього елемента (тобто до відповідному рядку даних).

Однак при виклику обробника події зв’язування з даними ви маєте справу з конкретним елементом управління, а не з шаблонним елементом. Тому вам доведеться пройти по ієрархічним дереву вгору від елемента управління до елемента шаблону. Найкраще для цього підходить властивість елемента керування NamingContainer, Що повертає посилання на елемент шаблону, в якому створено цей елемент керування. (Крім того, посилання на контейнер зберігає властивість Parent. Однак, якщо елемент управління вкладений в інший – наприклад, в Panel або Table, – Це властивість не поверне посилання на елемент шаблону.)

Таким чином, щоб зв’язати елемент керування у шаблоні з конкретними даними, необхідно зробити наступні дії.


Наступний код демонструє один із способів виконання необхідних дій (за основу взяті раніше наведені приклади). Це повний обробник події зв’язування з даними для елементів управління Literal, Створених для шаблонів.

Код створює змінну container типу RepeaterItem (Так як ми працюємо з елементом управління Repeater) І привласнює її властивості NamingContainer пов’язують елемента управління. Тепер за цим посиланням можна звернутися до DataItem контейнера-об’єкта. Це легко зробити, викликавши метод Eval об’єкту DataBinder (Цей же метод часто застосовується у виразах зв’язування з даними) і передавши йому посилання на об’єкт DataItem контейнера та ім’я необхідного поля.

Якщо у ваших шаблонах містяться елементи управління безлічі типів, створіть обробник події зв’язування з даними для кожного типу елемента керування.






” Visual Basic
Private Sub TemplateControl_DataBinding(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim lc As Literal
lc = CType(sender, Literal)
Dim container As RepeaterItem
container = CType(lc.NamingContainer, RepeaterItem)
lc.Text &= DataBinder.Eval(container.DataItem, “CategoryName”)
lc.Text &= “</TD></TR>”
End Sub
// C#
private void TemplateControl_DataBinding(object sender,
System.EventArgs e)
{
Literal lc;
lc = (Literal) sender;
RepeaterItem container = (RepeaterItem) lc.NamingContainer;
lc.Text += DataBinder.Eval(container.DataItem, “CategoryName”);
lc.Text += “</TD></TR>”;
}


Програмне створення шаблонів в елементі управління DataGrid


Вищеописана процедура працює для елементів управління Repeater і DataList. Крім того, можна програмно створювати шаблони для елемента керування DataGrid. Процес створення власне шаблону нічим не відрізняється. Але є відмінності в його використанні:


Коротко: в елементі управління DataGrid дозволені наступні типи стовпців:


Напевно, ви вже здогадалися, що саме для стовпців останнього типу програмно створюються шаблони. Іншими словами, якщо ви хочете змінювати елементи управління в стовпці DataGrid на етапі виконання, вам слід використовувати шаблонні стовпці і створювати шаблони “на льоту”.

У наступному прикладі показано, як створити два шаблони для елемента керування DataGrid і призначити їх стовпцях. Спочатку створюються шаблони, практично так само, як і в попередніх прикладах. Однак є два невеликі відмінності. По-перше, конструктор класу шаблону приймає два параметри, по другому параметрі передається ім’я створюваного стовпця. По-друге, в цей приклад включений код, який створює шаблон EditItem, Який створює елемент управління Textbox.






” Visual Basic
Private Class DataGridTemplate
Implements ITemplate
Dim templateType As ListItemType
Dim columnName As String
Sub New(ByVal type As ListItemType, ByVal ColName As String)
templateType = type
columnName = ColName
End Sub
Sub InstantiateIn(ByVal container As Control) _
Implements ITemplate.InstantiateIn
Dim lc As New Literal()
Select Case templateType
Case ListItemType.Header
lc.Text = “<B>” & columnName & “</B>”
container.Controls.Add(lc)
Case ListItemType.Item
lc.Text = “Item ” & columnName
container.Controls.Add(lc)
Case ListItemType.EditItem
Dim tb As New TextBox()
tb.Text = “”
container.Controls.Add(tb)
Case ListItemType.Footer
lc.Text = “<I>Footer</I>”
container.Controls.Add(lc)
End Select
End Sub
End Class
// C#
public class DataGridTemplate : ITemplate
{
ListItemType templateType;
string columnName;
public DataGridTemplate(ListItemType type, string colname)
{
templateType = type;
columnName = colname;
}
public void InstantiateIn(System.Web.UI.Control container)
{
Literal lc = new Literal();
switch(templateType)
{
case ListItemType.Header:
lc.Text = “<B>” + columnName + “</B>”;
container.Controls.Add(lc);
break;
case ListItemType.Item:
lc.Text = “Item ” + columnName;
container.Controls.Add(lc);
break;
case ListItemType.EditItem:
TextBox tb = new TextBox();
tb.Text = “”;
container.Controls.Add(tb);
break;
case ListItemType.Footer:
lc.Text = “<I>” + columnName + “</I>”;
container.Controls.Add(lc);
break;
}
}
}

У наступному прикладі демонструється створення шаблонів стовпців і призначення їх стовпцях.






” Visual Basic
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim tc1 As New TemplateColumn()
tc1.HeaderTemplate = New _
DataGridTemplate(ListItemType.Header, “Column1”)
tc1.ItemTemplate = New DataGridTemplate(ListItemType.Item, “Column1”)
tc1.EditItemTemplate = New _
DataGridTemplate(ListItemType.EditItem, “Column1”)
tc1.FooterTemplate = New _
DataGridTemplate(ListItemType.Footer, “Column1”)
DataGrid1.Columns.Add(tc1)

Dim tc2 As New TemplateColumn()
tc2.HeaderTemplate = New _
DataGridTemplate(ListItemType.Header, “Column2”)
tc2.ItemTemplate = New DataGridTemplate(ListItemType.Item, “Column2”)
tc2.EditItemTemplate = New _
DataGridTemplate(ListItemType.EditItem, “Column2”)
tc2.FooterTemplate = New _
DataGridTemplate(ListItemType.Footer, “Column2”)
DataGrid1.Columns.Add(tc2)
SqlDataAdapter1.Fill(DsCategories1)
DataGrid1.DataBind()
End Sub
// C#
private void Page_Load(object sender, System.EventArgs e)
{
TemplateColumn tc1 = new TemplateColumn();
tc1.HeaderTemplate = new
DataGridTemplate(ListItemType.Header, “Column1”);
tc1.ItemTemplate = new DataGridTemplate(ListItemType.Item, “Column1”);
tc1.EditItemTemplate = new
DataGridTemplate(ListItemType.EditItem, “Column1”);
tc1.FooterTemplate = new
DataGridTemplate(ListItemType.Footer, “Column1”);
DataGrid1.Columns.Add(tc1);
TemplateColumn tc2 = new TemplateColumn();
tc2.ItemTemplate = new DataGridTemplate(ListItemType.Item, “Column2”);
tc2.HeaderTemplate = new
DataGridTemplate(ListItemType.Header, “Column2”);
tc2.EditItemTemplate = new
DataGridTemplate(ListItemType.EditItem, “Column2”);
tc2.FooterTemplate = new
DataGridTemplate(ListItemType.Footer, “Column2”);
DataGrid1.Columns.Add(tc2);
sqlDataAdapter1.Fill(dataSet11);
DataGrid1.DataBind();
}



Висновок


Хоча приклади в цій статті досить прості, вони демонструють всі основні принципи створення шаблонів в коді. Звичайно, шаблони, які ви створите в своїх програмах, швидше за все виявляться набагато більш складними – всі шаблони в цій статті легко можна створити на етапі розробки. Але тепер ви знаєте достатньо, щоб створювати шаблони “на льоту”.


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*