Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

DataBound контролы


Visual Basic: новости сайтов, советы, примеры кодов

VBNet.Ru
Выпуск от Павла Сурменка



DataBound контролы

С субботы до понедельника у меня, к сожалению, не работала почта (были казусы с доменом), точнее один адрес – cdm@webreflection.ru . Поэтому, если вы мне писали на этот ящик и не получили ответа, отправьте пожалуйста сообщение еще раз.

 

Ниже предлагаю вашему вниманию небольшую статью об использовании контролов DataGrid и Repeater в ASP .NET.

 

Есть такая полезная вещь в ASP .NET как DataBound контролы (контролы, связанные с данными). Фактически они используются для отображения информации из структур данных (это могут быть DataTable, или коллекции собственных объектов, или еще какие-то объекты, созданные в расчете на использование как источник данных для контролов).

Наибольший интерес представляют контролы Repeater и DataGrid. Вместо DataGrid можно использовать GridView, который появился в ASP .NET 2.0: у него более можный функционал, правда эта мощь не всегда нужна, и я привык пользоваться DataGrid :)

В Repeater и DataGrid активно используется такая вещь как темплэйты (ItemTemplate, ColumnTemplate и т.д.). Они позволяют задать HTML-разметку для элемента данных. Ниже на примере это покажу.

Итак, Repetear. Преставьте, что в табличке БД 5 записей, в каждой записи поля: ID, название товара, цена. Надо их отобразить на странице. Причем не в виде грида, а так чтобы это выглядело вот так примерно:

 

Audi A8 Security [купить]

250000 USD

--

Wolksvagen Toureg [купить]

60000 USD

--

Запорожец горбатый [купить]

100 USD

 

Вот именно это позволяет сделать Repeater. В нем задается ItemTemplate – шаблон одной единицы данных, и в программном коде он привызывается (bind) к набору данных (в нашем примере привяжем в DataTable, которую вы предварительно заполнили данными из БД с помощью DataAdapter).

ItemTemplate – это по сути что-то вот такое:

 

название [купить(в ссылку подставляется ID товара)]

цена USD

 

То есть задается HTML-разметка, в нужных местах вставляются ASP .NET контролы, в них указывается – из каких полей БД брать значения для свойств.

Repeater в aspx странице будет выглядеть так:

<asp:Repeater ID="ProductsRepeater" runat="server">

    <ItemTemplate>

        <asp:Label ID="TitleLabel" runat="server" Text='<%# Eval("Title") %>' style=""font-weight:bold;"" />

        <asp:HyperLink ID="BuyLink" runat="server"

            NavigateUrl='<%# String.Format("~/BuyProduct.aspx?id={0}", Eval("ID")) %>'

            Text="[Купить]"

            /><br />

        <asp:Label ID="PriceLabel" runat="server" Text='<%# Eval("Price") %>' /> USD

    </ItemTemplate>

    <SeparatorTemplate>

        <br /><hr /><br />

    </SeparatorTemplate>

</asp:Repeater>

 

Итак, что мы видим? В репитере задан ItemTemplate, внутри него 3 контрола и необходимые HTML-контролы для того чтобы всё выглядело как надо. В контролах вместо значений нужных свойств прописаны выражения, которые подставляют в значение свойства значание поля элемента данных. Выражение пишется внутри вот таких вот штуковин: <%# %> Самый простой вариант получения значения поля элемента – это вызвать функцию Eval, передав в нее имя поля. Есть варианты и посложнее, о них позже.

Можно не только просто подставить значение поля, с этими данными можно проводить какие угодно действия. Скажем для указания NavigateURL (это URL ссылки) я использовал метод String.Format, в который передал ID элемента данных. Можно проводить любые операции, можно даже к примеру вызвать метод, который вы создали ранее в codebehind страницы (толкьо метод этот нужно пометить как Protected) – чтобы вынести какие-то сложные вычисления в этот метод. В общем, простор для творчества велик.

Еще я там задал SeparatorTemplate – это тот HTML-код, который будет располагаться между элементами данных. Кроме этих темплэйтов там еще несколько можно задавать типа HeaderTemplate, FooterTemplate и т.д.

Теперь надо этот Repeater заполнить данными. Это также предельно просто делается. Вставляем в Page_Load (обработчик события Load страницы) такой код:

If Not Me.IsPostBack Then

    Dim ProductsDT As New DataTable()

    ‘Тут каким-то образом вы из БД данные получаете и

    ‘сливаете их в DataTable

    Me.ProductsRepeater.DataSource = ProductsDT

    Me.ProductsRepeater.DataBind()

End If

 

То есть просто присваиваете источник данных свойству DataSource, и вызываете DataBind. Реально данные привязываются к репитеру именно при вызове DataBind.

В DataGrid всё так же, только темплэйт надо задавать для каждой колонки. Т.е. если будем отображать в гриде 6 колонок – пишем 6 темплэйтов, по одному на колонку. Привязывается к данным он точно так же как репитер – ставим DataSource, вызываем DataBind. Ниже пример.

 

<asp:DataGrid ID="OrdersGrid" runat="server"

    AutoGenerateColumns="false" Width="100%">

    <Columns>

        <asp:TemplateColumn HeaderText="ID счета">

            <ItemTemplate>

                <asp:Label ID="IDLabel" runat="server"

                    Text='<%# Eval("ID") %>' />

            </ItemTemplate>

        </asp:TemplateColumn>

        <asp:TemplateColumn HeaderText="Дата/время">

            <ItemTemplate>

                <asp:Label ID="DateTimeLabel" runat="server"

                    Text='<%# CType(Eval("Date"), DateTime).ToString("dd.MM.yyyy HH:mm:ss") %>' />

            </ItemTemplate>

        </asp:TemplateColumn>

        <asp:TemplateColumn HeaderText="Сумма">

            <ItemTemplate>

                <asp:Label ID="AmountWMLabel" runat="server"

                    Text='<%# Eval("Ammount") %>' />

            </ItemTemplate>

        </asp:TemplateColumn>

        <asp:TemplateColumn HeaderText="WMID">

            <ItemTemplate>

                <asp:Label ID="WMIDLabel" runat="server"

                    Text='<%# Eval("WMID") %>' />

            </ItemTemplate>

        </asp:TemplateColumn>

        <asp:TemplateColumn HeaderText="Тип оплаты">

            <ItemTemplate>

                <asp:Label ID="PayMethodLabel" runat="server"

                    Text='<%# IIF(CType(Eval("PayMethod"), Int32)=1, "Merchant", "Счет") %>' />

            </ItemTemplate>

        </asp:TemplateColumn>

        <asp:TemplateColumn HeaderText="Оплачено">

            <ItemTemplate>

                <asp:Label ID="PayedLabel" runat="server"

                    Text='<%# IIF(CType(Eval("Payed"), Boolean)=True, "Да", "Нет") %>' />

            </ItemTemplate>

        </asp:TemplateColumn>

        <asp:TemplateColumn HeaderText="Подробнее...">

            <ItemTemplate>

                <asp:LinkButton ID="DetailsLink" runat="server"

                    CommandName="details" CommandArgument='<%# Eval("ID") %>'

                    Text="Подробнее..." />

            </ItemTemplate>

        </asp:TemplateColumn>

    </Columns>

</asp:DataGrid>

 

Это я выдернул из реального приложения (правда немного обрезал, там раза в три больше колонок было).

Еще один момент пояснить надо. Это использование Button (а также других подобных контролов, например LinkButton) внутри грида и репитера. Вот, вы видите, в последней колонке стоит LinkButton, у него кроме Text назначены еще 2 свойства: CommandName и CommandArgument. В первом надо указать название команды, которую выполняет этот контрол, во втором – аргумент команды. Зачем название – затем, что их вы можете понатыкать в грид десяток, и надо их между собой различать будет. В команду я прописал “details”, а в аргумент прибиндил значение поля ID. Далее надо клик по этому LinkButton обработать как-то. Для этого делаем обработчик события ItemCommand грида (для репитера всё точно так же).

 

Protected Sub OrdersGrid_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles OrdersGrid.ItemCommand

    Select Case e.CommandName.ToLower

        Case "details"

            Dim ID As Int32 = CType(e.CommandArgument, Int32)

 

            ‘Получили ID, теперь делаем что душе угодно.

            ‘В моем случае я получил по ID запись из БД, и показал

            ‘ее значения в отдельных контролах

 

        Case "delete"

            Dim ID As Int32 = CType(e.CommandArgument, Int32)

 

            ‘А это уже обработка другого действия – клика на кнопку «Удалить» из

            ‘другой колонки, которую я в вышеуказанный код не включил

 

    End Select

End Sub

 

 

Павел Сурменок

VBNet

Web Reflection

 


В избранное