Bir Ayrıntılar DataList’i ile Madde İşaretli Ana Kayıt Listesi Kullanan Ana/Ayrıntı (VB)

tarafından Scott Mitchell

PDF’yi İndir

Bu öğreticide, önceki öğreticinin iki sayfalık ana/ayrıntı raporunu, ekranın sol tarafında kategori adlarının madde işaretli listesini ve ekranın sağ tarafında seçili kategorinin ürünlerini gösteren tek bir sayfada sıkıştıracağız.

Giriş

Önceki öğreticide bir ana/ayrıntı raporunu iki sayfaya ayırmayı inceledik. Ana sayfada madde işaretli kategori listesini işlemek için Repeater denetimi kullandık. Her kategori adı, tıklandığında kullanıcıyı iki sütunlu bir DataList'in seçili kategoriye ait ürünleri gösterdiği ayrıntılar sayfasına götüren bir köprü idi.

Bu öğreticide, iki sayfalık öğreticiyi tek bir sayfada sıkıştıracak ve ekranın sol tarafında her kategori adının LinkButton olarak işlendiği kategori adlarının madde işaretli bir listesini göstereceğiz. LinkButtons kategori adından birine tıklanması geri göndermeye neden olur ve seçili kategorinin ürünlerini ekranın sağındaki iki sütunlu bir DataList'e bağlar. Soldaki Yineleyici, her kategorinin adını görüntülemeye ek olarak, belirli bir kategori için toplam kaç ürün olduğunu gösterir (bkz. Şekil 1).

Kategori Adı ve Toplam Ürün Sayısı Sol Tarafta Görüntülenir

Şekil 1: Kategori Adı ve Toplam Ürün Sayısı Solda Görüntülenir (Tam boyutlu resmi görüntülemek için tıklayın)

1. Adım: Ekranın Sol Kısmında Yineleyici Görüntüleme

Bu öğretici için, seçilen kategori ürünlerinin solunda madde işaretli kategori listesinin gösterilmesi gerekir. Web sayfası içindeki içerik standart HTML öğeleri paragraf etiketleri, kesme olmayan boşluklar, <table> s, vb. kullanılarak veya basamaklı stil sayfası (CSS) teknikleri aracılığıyla konumlandırılabilir. Şimdiye kadarki tüm öğreticilerimizde konumlandırma için CSS teknikleri kullanılmıştır. Ana Sayfalar ve Site Gezintisi öğreticisinde ana sayfamızda gezinti kullanıcı arabirimini oluşturduğumuzda, gezinti listesi ve ana içerik için tam piksel uzaklığını gösteren mutlak konumlandırmayı kullandık. Alternatif olarak CSS, kayan öğe aracılığıyla bir öğeyi diğerinin sağ veya soluna konumlandırmak için kullanılabilir. Madde işaretli kategori listesinin, DataList öğesinin solundaki Repeater'ı kaydırarak seçili kategori ürünlerinin solunda görünmesini sağlayabiliriz

Klasörden sayfayı CategoriesAndProducts.aspxDataListRepeaterFiltering açın ve sayfaya Repeater ve DataList ekleyin. Repeater'ı ID olarak Categories , DataList'leri CategoryProductsolarak ayarlayın. Kaynak görünümüne gidin ve Repeater ve DataList denetimlerini kendi <div> öğelerine yerleştirin. Başka bir ifadeyle, Repeater'ı önce bir <div> öğenin içine, sonra da Repeater'ın hemen ardından datalist öğesini kendi <div> öğesi içine alın. Bu noktadaki işaretlemeniz aşağıdakine benzer olmalıdır:

<div>
    <asp:Repeater ID="Categories" runat="server">
    </asp:Repeater>
</div>
<div>
    <asp:DataList ID="CategoryProducts" runat="server">
    </asp:DataList>
</div>

Repeater'ı DataList'in soluna kaydırmak için CSS stili özniteliğini float kullanmamız gerekir, örneğin:

<div>
    Repeater
</div>
<div>
    DataList
</div>

, float: left; birinci <div> öğeyi ikinci öğenin soluna kaydırıyor. ve padding-right ayarları, width öğenin içeriğiyle sağ kenar boşluğu arasına <div> ilk <div>width s ve ne kadar doldurma eklendiğini gösterir. CSS'de kayan öğeler hakkında daha fazla bilgi için Floatutorial'a göz atın.

Stil ayarını doğrudan ilk <p> öğenin style özniteliği aracılığıyla belirtmek yerine adlı yeni bir CSS sınıfı Styles.cssFloatLeftoluşturalım:

.FloatLeft
{
    float: left;
    width: 33%;
    padding-right: 10px;
}

Ardından değerini <div> ile <div class="FloatLeft">değiştirebiliriz.

CSS sınıfını ekledikten ve sayfada işaretlemeyi CategoriesAndProducts.aspx yapılandırdıktan sonra Tasarım Aracı gidin. DataList'in solunda Repeater'ın kayan olduğunu görmeniz gerekir (şu anda her ikisi de veri kaynaklarını veya şablonlarını yapılandırmadığımız için yalnızca gri kutular olarak görünse de).

Repeater, DataList'in Soluna Kaydırılır

Şekil 2: Repeater, DataList'in Soluna Kaydırılır (Tam boyutlu görüntüyü görüntülemek için tıklayın)

2. Adım: Her Kategori için Ürün Sayısını Belirleme

Repeater ve DataList çevresindeki işaretleme tamamlandıktan sonra kategori verilerini Repeater denetimine bağlamaya hazırız. Bununla birlikte, Şekil 1'deki madde işaretli kategori listesi gösterildiği gibi, her kategorinin adına ek olarak kategoriyle ilişkili ürün sayısını da görüntülememiz gerekir. Bu bilgilere erişmek için şunları yapabilirsiniz:

  • Bu bilgileri ASP.NET sayfasının arka planda kod sınıfından belirleyin. Belirli categoryID bir nedenle, sınıfın GetProductsByCategoryID(categoryID) yöntemini çağırarak ProductsBLL ilişkili ürünlerin sayısını belirleyebiliriz. Bu yöntem, özelliği belirtilen için categoryIDürün sayısı olan kaç ProductsRow tane var olduğunu gösteren bir ProductsDataTable nesnesi Count döndürür. Repeater için Repeater'a bağlı her kategori için sınıfın ProductsBLLGetProductsByCategoryID(categoryID) yöntemini çağıran ve çıkışta sayıyı içeren bir ItemDataBound olay işleyicisi oluşturabiliriz.
  • CategoriesDataTable Türü Yazılan Veri Kümesindeki öğesini bir NumberOfProducts sütun içerecek şekilde güncelleştirin. Ardından yöntemini bu bilgileri içerecek şekilde güncelleştirebilir GetCategories()CategoriesDataTable veya alternatif olarak olduğu gibi bırakıp GetCategories() adlı GetCategoriesAndNumberOfProducts()yeni CategoriesDataTable bir yöntem oluşturabiliriz.

Şimdi bu tekniklerin ikisini de inceleyelim. Veri Erişim Katmanı'nı güncelleştirmemiz gerekmeyen ilk yaklaşımı uygulamak daha kolaydır; ancak veritabanıyla daha fazla iletişim gerektirir. Olay işleyicisindeki sınıfın ProductsBLLGetProductsByCategoryID(categoryID) yöntemine yapılan ItemDataBound çağrı, Repeater'da görüntülenen her kategori için ek bir veritabanı çağrısı ekler. Bu teknikle N + 1 veritabanı çağrıları vardır; burada N , Repeater'da görüntülenen kategori sayısıdır. İkinci yaklaşımla, ürün sayısı sınıfının GetCategories() (veya GetCategoriesAndNumberOfProducts()) yönteminden CategoriesBLL her kategoriyle ilgili bilgilerle döndürülür ve bu da veritabanına tek bir yolculukla sonuçlanır.

ItemDataBound Olay İşleyicisindeki Ürün Sayısını Belirleme

Repeater ItemDataBound olay işleyicisindeki her kategori için ürün sayısını belirlemek için mevcut Veri Erişim Katmanımızda herhangi bir değişiklik yapılması gerekmez. Tüm değişiklikler doğrudan sayfanın içinden CategoriesAndProducts.aspx yapılabilir. Repeater'ın akıllı etiketi aracılığıyla adlı CategoriesDataSource yeni bir ObjectDataSource ekleyerek başlayın. Ardından, ObjectDataSource'u CategoriesDataSource sınıfın CategoriesBLLGetCategories() yönteminden verilerini alacak şekilde yapılandırın.

ObjectDataSource'ı CategoriesBLL sınıfının GetCategories() Yöntemini Kullanacak Şekilde Yapılandırma

Şekil 3: ObjectDataSource'un Sınıfın CategoriesBLLGetCategories() Yöntemini Kullanacak Şekilde Yapılandırma (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Repeater'daki Categories her öğenin tıklanabilir olması ve tıklandığında DataList'in CategoryProducts seçilen kategori için bu ürünleri görüntülemesine neden olması gerekir. Bu, önceki öğreticide gördüğümüz gibi her kategoriyi köprü haline getirerek, aynı sayfaya ()CategoriesAndProducts.aspx bağlanarak ancak sorgu dizesinden geçirerek CategoryID gerçekleştirilebilir. Bu yaklaşımın avantajı, belirli bir kategorinin ürünlerini görüntüleyen bir sayfanın arama motoru tarafından yer işareti ve dizine alınabilmesidir.

Alternatif olarak, her kategoriyi bu öğreticide kullanacağımız bir LinkButton yöntemi haline getirebilirsiniz. LinkButton, kullanıcının tarayıcısında köprü olarak işlenir, ancak tıklandığında bir geri göndermeye neden olur; geri gönderildiğinde, seçilen kategoriye ait ürünleri görüntülemek için DataList'in ObjectDataSource'unun yenilenmesi gerekir. Bu öğreticide, köprü kullanmak LinkButton kullanmaktan daha anlamlıdır; ancak LinkButton kullanmanın daha avantajlı olduğu başka senaryolar da olabilir. Köprü yaklaşımı bu örnek için ideal olsa da, bunun yerine LinkButton'ı kullanarak keşfedelim. Göreceğimiz gibi, LinkButton kullanmak köprüyle ortaya çıkmayacak bazı zorluklara neden olur. Bu nedenle, bu öğreticide bir LinkButton kullanmak bu zorlukları vurgular ve köprü yerine LinkButton kullanmak isteyebileceğimiz senaryolar için çözümler sağlamaya yardımcı olur.

Not

Bu öğreticiyi LinkButton'ın yanı sıra bir HyperLink denetimi veya <a> öğesi kullanarak tekrarlamanız teşvik edilir.

Aşağıdaki işaretlemede Repeater ve ObjectDataSource için bildirim temelli söz dizimi gösterilmektedir. Repeater şablonlarının her öğeyi LinkButton olarak madde işaretli bir liste olarak işlediğini unutmayın:

<asp:Repeater ID="Categories" runat="server" DataSourceID="CategoriesDataSource">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li><asp:LinkButton runat="server" ID="ViewCategory"></asp:LinkButton></li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

Not

Bu öğretici için Repeater'ın görünüm durumunun etkin olması gerekir (Repeater'ın bildirim temelli söz diziminden atlanan öğesini not edin EnableViewState="False" ). 3. adımda, DataList'in ItemCommand ObjectDataSource SelectParameters koleksiyonunu güncelleştireceğimiz Repeater olayı için bir olay işleyicisi oluşturacağız. Ancak görüntüleme durumu devre dışı bırakılırsa Repeater'ın ItemCommand'ı tetiklenemez.

özelliği değerine ViewCategory sahip ID LinkButton'ın Text özelliği ayarlanmadı. Yalnızca kategori adını görüntülemek isteseydik Text özelliğini veri bağlama söz dizimi aracılığıyla bildirim temelli olarak ayarlardık, örneğin:

<asp:LinkButton runat="server" ID="ViewCategory"
    Text='<%# Eval("CategoryName") %>' />

Ancak, hem kategorinin adını hem de bu kategoriye ait ürünlerin sayısını göstermek istiyoruz. Bu bilgiler, aşağıdaki kodda gösterildiği gibi sınıfının yöntemine ProductBLL bir çağrı yapılarak ve sonuçta ProductsDataTablekaç kayıt döndürülür belirlenerek Repeater'ın ItemDataBoundGetCategoriesByProductID(categoryID) olay işleyicisinden alınabilir:

Protected Sub Categories_ItemDataBound(sender As Object, e As RepeaterItemEventArgs)
    ' Make sure we're working with a data item...
    If e.Item.ItemType = ListItemType.Item OrElse _
        e.Item.ItemType = ListItemType.AlternatingItem Then
        ' Reference the CategoriesRow instance bound to this RepeaterItem
        Dim category As Northwind.CategoriesRow = _
            CType(CType(e.Item.DataItem, System.Data.DataRowView).Row, _
                Northwind.CategoriesRow)
        ' Determine how many products are in this category
        Dim productsAPI As New NorthwindTableAdapters.ProductsTableAdapter
        Dim productCount As Integer = _
            productsAPI.GetProductsByCategoryID(category.CategoryID).Count
        ' Reference the ViewCategory LinkButton and set its Text property
        Dim ViewCategory As LinkButton = _
            CType(e.Item.FindControl("ViewCategory"), LinkButton)
        ViewCategory.Text = _
            String.Format("{0} ({1:N0})", category.CategoryName, productCount)
    End If
End Sub

İlk olarak bir veri öğesiyle (veya AlternatingItemolan ItemItemType bir öğe) çalıştığımızdan emin oluyor ve ardından geçerli RepeaterItemöğesine bağlı olan örneğe başvuruyoruzCategoriesRow. Ardından, sınıfının bir örneğini ProductsBLL oluşturarak, yöntemini çağırarak GetCategoriesByProductID(categoryID) ve özelliğini kullanarak döndürülen kayıt sayısını belirleyerek bu kategori için Count ürün sayısını belirleriz. Son olarak, ViewCategory ItemTemplate içindeki LinkButton başvurudur ve Text özelliği CategoryName (NumberOfProductsInCategory) olarak ayarlanır; burada NumberOfProductsInCategory , ondalık basamakları sıfır olan bir sayı olarak biçimlendirilir.

Not

Alternatif olarak, ASP.NET sayfasının arka kod arkası sınıfına bir kategori s CategoryName ve değerlerini kabul eden ve CategoryID kategorideki CategoryName ürün sayısıyla birleştirilmiş (yöntemini çağırarak GetCategoriesByProductID(categoryID) belirlendiği gibi) döndüren bir biçimlendirme işlevi eklemiş olabilirdik. Böyle bir biçimlendirme işlevinin sonuçları, olay işleyici gereksinimini değiştirerek LinkButton'ın Text özelliğine ItemDataBound bildirimli olarak atanabilir. Biçimlendirme işlevlerini kullanma hakkında daha fazla bilgi için GridView Denetiminde TemplateField Kullanma veya DataList ve Repeater'ı Verilere Göre Biçimlendirme öğreticilerine bakın.

Bu olay işleyicisini ekledikten sonra, sayfayı tarayıcı üzerinden test etmek için biraz zaman ayırın. Her kategorinin madde işaretli listede nasıl listelendiğini ve kategorinin adını ve kategoriyle ilişkili ürün sayısını görüntülediğini unutmayın (bkz. Şekil 4).

Her Kategorinin Adı ve Ürün Sayısı Görüntülenir

Şekil 4: Her Kategorinin Adı ve Ürün Sayısı Görüntülenir (Tam boyutlu resmi görüntülemek için tıklayın)

Ve'yiCategoriesDataTableCategoriesTableAdapterHer Kategori için Ürün Sayısını Içerecek Şekilde Güncelleştirme

Repeater'a bağlı olarak her kategori için ürün sayısını belirlemek yerine ve veri erişim katmanında bu bilgileri yerel olarak içerecek şekilde ayarlayarak CategoriesDataTableCategoriesTableAdapter bu işlemi kolaylaştırabiliriz. Bunu başarmak için, ilişkili ürünlerin sayısını tutmak için yeni CategoriesDataTable bir sütun eklemeliyiz. DataTable'a yeni sütun eklemek için, Yazılan DataSet()App_Code\DAL\Northwind.xsd öğesini açın, değiştirmek için DataTable'a sağ tıklayın ve Ekle / Sütun'u seçin. öğesine CategoriesDataTable yeni bir sütun ekleyin (bkz. Şekil 5).

CategoriesDataSource'a Yeni Sütun Ekleme

Şekil 5: Öğesine Yeni Sütun CategoriesDataSource Ekleme (Tam boyutlu resmi görüntülemek için tıklayın)

Bu, yalnızca farklı bir ad yazarak değiştirebileceğiniz adlı Column1yeni bir sütun ekler. Bu yeni sütunu olarak NumberOfProductsyeniden adlandırın. Ardından, bu sütunun özelliklerini yapılandırmamız gerekir. Yeni sütuna tıklayın ve Özellikler penceresi gidin. sütununun DataType özelliğini System.Int32System.String olarak değiştirin ve Şekil 6'da gösterildiği gibi özelliğini Trueolarak ayarlayınReadOnly.

Yeni Sütunun DataType ve ReadOnly Özelliklerini Ayarlama

Şekil 6: Yeni Sütunun DataType ve ReadOnly Özelliklerini Ayarlama

CategoriesDataTable şimdi bir NumberOfProducts sütuna sahip olsa da, değeri ilgili TableAdapter sorgularından herhangi biri tarafından ayarlanmaz. Kategori bilgileri her alındığında bu bilgilerin döndürülmesini istiyorsak bu bilgileri döndürmek için yöntemini güncelleştirebiliriz GetCategories() . Ancak, nadir durumlardaki kategoriler için ilişkili ürünlerin sayısını (yalnızca bu öğreticide olduğu gibi) yakalamamız gerekiyorsa olduğu gibi bırakabilir GetCategories() ve bu bilgileri döndüren yeni bir yöntem oluşturabiliriz. Bu ikinci yaklaşımı kullanarak adlı GetCategoriesAndNumberOfProducts()yeni bir yöntem oluşturalım.

Bu yeni GetCategoriesAndNumberOfProducts() yöntemi eklemek için öğesine sağ tıklayın CategoriesTableAdapter ve Yeni Sorgu'yu seçin. Bu, önceki öğreticilerde birçok kez kullandığımız TableAdapter Sorgu Yapılandırma Sihirbazı'nı getirir. Bu yöntem için, sorgunun satırları döndüren geçici bir SQL deyimi kullandığını belirterek sihirbazı başlatın.

Geçici SQL Deyimi Kullanarak Yöntemi Oluşturma

Şekil 7: Geçici SQL Deyimi Kullanarak Yöntem Oluşturma (Tam boyutlu görüntüyü görüntülemek için tıklayın)

SQL Deyimi Satırları Döndürür

Şekil 8: SQL Deyimi Satır Döndürüyor (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Sonraki sihirbaz ekranı sorgunun kullanılmasını ister. Her kategorinin CategoryID, CategoryNameve Description alanlarının yanı sıra kategoriyle ilişkili ürün sayısını döndürmek için aşağıdaki SELECT deyimi kullanın:

SELECT CategoryID, CategoryName, Description,
       (SELECT COUNT(*) FROM Products p WHERE p.CategoryID = c.CategoryID)
            as NumberOfProducts
FROM Categories c

Kullanılacak Sorguyu Belirtme

Şekil 9: Kullanılacak Sorguyu Belirtin (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Kategoriyle ilişkili ürün sayısını hesaplayan alt sorgunun olarak NumberOfProductsdiğer adlara sahip olduğunu unutmayın. Bu adlandırma eşleşmesi, bu alt sorgu tarafından döndürülen değerin s NumberOfProducts sütunuyla ilişkilendirilmesine CategoriesDataTable neden olur.

Bu sorguyu girdikten sonra, son adım yeni yöntemin adını seçmektir. Sırasıyla Bir DataTable Doldurma ve DataTable Döndürme desenleri için ve GetCategoriesAndNumberOfProducts kullanınFillWithNumberOfProducts.

Yeni TableAdapter Yöntemlerini FillWithNumberOfProducts ve GetCategoriesAndNumberOfProducts olarak adlandırın

Şekil 10: Yeni TableAdapter Yöntemlerini adlandırın FillWithNumberOfProducts ve GetCategoriesAndNumberOfProducts (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Bu noktada Veri Erişim Katmanı, kategori başına ürün sayısını içerecek şekilde genişletilmiştir. Tüm sunu katmanımız DAL'ye yapılan tüm çağrıları ayrı bir İş Mantığı Katmanı üzerinden yönlendirdiğinden sınıfına CategoriesBLL karşılık gelen GetCategoriesAndNumberOfProducts bir yöntem eklememiz gerekir:

<System.ComponentModel.DataObjectMethodAttribute _
    (System.ComponentModel.DataObjectMethodType.Select, False)> _
Public Function GetCategoriesAndNumberOfProducts() As Northwind.CategoriesDataTable
    Return Adapter.GetCategoriesAndNumberOfProducts()
End Function

DAL ve BLL tamamlandıktan sonra, bu verileri içindeki CategoriesAndProducts.aspxRepeater'a Categories bağlamaya hazırız! Olay İşleyicisi'nde ItemDataBound Ürün Sayısını Belirleme bölümünden Repeater için zaten bir ObjectDataSource oluşturduysanız, bu ObjectDataSource'u silin ve Repeater özellik DataSourceID ayarını kaldırın; ayrıca arkadaki kod ASP.NET sınıfındaki söz dizimini kaldırarak Repeater ItemDataBound olayının bağlantısını olay işleyicisinden kaldırın Handles Categories.OnItemDataBound .

Repeater özgün durumuna geri döndüğünde Repeater'ın akıllı etiketi aracılığıyla adlı CategoriesDataSource yeni bir ObjectDataSource ekleyin. ObjectDataSource'u sınıfını CategoriesBLL kullanacak şekilde yapılandırın, ancak yöntemini kullanmak GetCategories() yerine kullanın GetCategoriesAndNumberOfProducts() (bkz. Şekil 11).

ObjectDataSource'ı GetCategoriesAndNumberOfProducts Yöntemini Kullanacak Şekilde Yapılandırma

Şekil 11: ObjectDataSource'un Yöntemini Kullanacak Şekilde Yapılandırılması GetCategoriesAndNumberOfProducts (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Ardından, LinkButton s Text özelliğinin veri bağlama söz dizimi kullanılarak bildirim temelli olarak atanması ve hem hem NumberOfProducts de veri alanlarını içermesi CategoryName için öğesini güncelleştirinItemTemplate. Repeater ve ObjectDataSource için bildirim temelli işaretlemenin CategoriesDataSource tamamı şu şekildedir:

<asp:Repeater ID="Categories" runat="server" DataSourceID="CategoriesDataSource">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li><asp:LinkButton runat="server" ID="ViewCategory"
                Text='<%# String.Format("{0} ({1:N0})", _
                    Eval("CategoryName"), Eval("NumberOfProducts")) %>' />
        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetCategoriesAndNumberOfProducts" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

DAL'yi bir NumberOfProducts sütun içerecek şekilde güncelleştirerek işlenen çıkış, olay işleyicisi yaklaşımını ItemDataBound kullanmakla aynıdır (kategori adlarını ve ürün sayısını gösteren Repeater'ın ekran görüntüsünü görmek için Şekil 4'e geri bakın).

3. Adım: Seçili Kategorinin Ürünlerini Görüntüleme

Bu noktada, kategori listesini ve her kategorideki ürün sayısını görüntüleyen Repeater'a sahibiz Categories . Repeater, tıklandığında geri göndermeye neden olan her kategori için bir LinkButton kullanır ve bu noktada DataList'te CategoryProducts seçili kategori için bu ürünleri görüntülememiz gerekir.

Karşılaştığımız zorluklardan biri, DataList'in yalnızca seçilen kategoriye yönelik ürünleri görüntülemesini sağlamaktır. DetailsView ile Seçilebilir Ana/Ayrıntı GridView Kullanma öğreticisinde, satırları seçilebilen bir GridView oluşturmayı ve seçilen satırın ayrıntılarının aynı sayfadaki DetailsView'da görüntülenmesini gördük. GridView s ObjectDataSource, s GetProducts() yöntemini kullanarak ProductsBLL tüm ürünler hakkında bilgi döndürürken DetailsView s ObjectDataSource, yöntemini kullanarak GetProductsByProductID(productID) seçili ürün hakkındaki bilgileri alır. productID Parametre değeri GridView s SelectedValue özelliğinin değeriyle ilişkilendirilerek bildirim temelli olarak sağlanmıştır. Ne yazık ki Repeater'ın bir SelectedValue özelliği yoktur ve parametre kaynağı olarak hizmet veremez.

Not

Bu, Repeater'da LinkButton kullanılırken ortaya çıkan zorluklardan biridir. Bunun yerine querystring aracılığıyla geçirmek CategoryID için bir köprü kullansaydık, parametrenin değeri için kaynak olarak bu QueryString alanını kullanabilirdik.

Yine de Repeater için bir SelectedValue özelliğin olmaması konusunda endişelenmeden önce önce DataList'i bir ObjectDataSource'a bağlayıp belirtelim ItemTemplate.

DataList'in akıllı etiketinden adlı CategoryProductsDataSource yeni bir ObjectDataSource eklemeyi ve sınıfın GetProductsByCategoryID(categoryID) yöntemini kullanacak şekilde yapılandırmayı ProductsBLL tercih edin. Bu öğreticideki DataList salt okunur bir arabirim sunduğundan INSERT, UPDATE ve DELETE sekmelerindeki açılan listeleri (Yok) olarak ayarlayabilirsiniz.

ObjectDataSource'ı ProductsBLL Sınıfının GetProductsByCategoryID(categoryID) Yöntemini Kullanacak Şekilde Yapılandırma

Şekil 12: ObjectDataSource'ı GetProductsByCategoryID(categoryID) Sınıf Yöntemini Kullanacak ProductsBLL Şekilde Yapılandırma (Tam boyutlu görüntüyü görüntülemek için tıklayın)

GetProductsByCategoryID(categoryID) yöntemi bir giriş parametresi ()categoryID beklediğinden, Veri Kaynağını Yapılandırma sihirbazı parametrenin kaynağını belirtmemize olanak tanır. Kategoriler GridView'da veya DataList'te listelenseydi, Parametre kaynağı açılan listesini Control, ControlID değerini de veri Web denetiminin ID değeri olarak ayarlardık. Ancak Repeater özelliğine sahip SelectedValue olmadığından parametre kaynağı olarak kullanılamaz. Kontrol ederseniz, ControlID açılan listesinde DataList'in yalnızca bir denetimi ID``CategoryProductsID olduğunu görürsünüz.

Şimdilik Parametre kaynağı açılan listesini Yok olarak ayarlayın. Repeater'da LinkButton kategorisine tıklandığında bu parametre değerini program aracılığıyla atayacağız.

categoryID Parametresi için Parametre Kaynağı Belirtme

Şekil 13: Parametre için categoryID Parametre Kaynağı Belirtme (Tam boyutlu görüntüyü görüntülemek için tıklayın)

Veri Kaynağını Yapılandırma sihirbazını tamamladıktan sonra Visual Studio, DataList'in ItemTemplateöğesini otomatik olarak oluşturur. Bu varsayılan değeri ItemTemplate önceki öğreticide kullandığımız şablonla değiştirin; ayrıca DataList özelliğini RepeatColumns 2 olarak ayarlayın. Bu değişiklikleri yaptıktan sonra DataList'iniz ve ilişkili ObjectDataSource'unuz için bildirim temelli işaretleme aşağıdaki gibi görünmelidir:

<asp:DataList ID="CategoryProducts" runat="server" DataKeyField="ProductID"
    DataSourceID="CategoryProductsDataSource" RepeatColumns="2"
    EnableViewState="False">
    <ItemTemplate>
        <h5><%# Eval("ProductName") %></h5>
        <p>
            Supplied by <%# Eval("SupplierName") %><br />
            <%# Eval("UnitPrice", "{0:C}") %>
        </p>
    </ItemTemplate>
</asp:DataList>
<asp:ObjectDataSource ID="CategoryProductsDataSource"
    OldValuesParameterFormatString="original_{0}"  runat="server"
    SelectMethod="GetProductsByCategoryID" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:Parameter Name="categoryID" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

Şu anda ObjectDataSource CategoryProductsDataSourcecategoryID parametresi hiçbir zaman ayarlanmamıştır, bu nedenle sayfa görüntülenirken hiçbir ürün görüntülenmez. Yapmamız gereken bu parametre değerini Yineleyici'deki tıklanan kategoriye göre CategoryID ayarlamaktır. Bu iki zorluk oluşturur: birincisi, Repeater'lardaki ItemTemplate bir LinkButton'a ne zaman tıklandığını nasıl belirleyebiliriz ve ikincisi, LinkButton'a tıklanan ilgili kategoriyi nasıl belirleyebiliriz CategoryID ?

Button ve ImageButton denetimleri gibi LinkButton'ın bir Click olayı ve bir Command olayı vardır. Olay Click yalnızca LinkButton düğmesine tıklandığını not etmek için tasarlanmıştır. Ancak bazen LinkButton'a tıklandığının belirtilmesine ek olarak olay işleyicisine bazı ek bilgiler de geçirmemiz gerekir. Böyle bir durumda LinkButton s CommandName ve CommandArgument özelliklerine bu ek bilgiler atanabilir. Ardından, LinkButton düğmesine tıklandığında, Command olayı tetikler (olayı yerineClick) ve olay işleyicisi ve CommandArgument özelliklerinin değerlerine CommandName geçirilir.

Repeater'daki bir şablonun içinden bir Command olay tetiklendiğinde Repeater'ınItemCommand olayı tetiklenir ve tıklanan LinkButton'ın (veya Button veya ImageButton) ve CommandArgument değerlerine geçirilirCommandName. Bu nedenle Repeater'daki LinkButton kategorisine ne zaman tıklandığını belirlemek için aşağıdakileri yapmamız gerekir:

  1. CommandName Repeater'lardaki ItemTemplate LinkButton özelliğini bir değere ayarlayın (ListProducts kullandım). Bu CommandName değer ayarlandığında, LinkButton'a Command tıklandığında LinkButton olayı tetikler.
  2. LinkButton s CommandArgument özelliğini geçerli öğenin CategoryIDdeğerine ayarlayın.
  3. Repeater ItemCommand olayı için bir olay işleyicisi oluşturun. Olay işleyicisinde ObjectDataSource parametresini CategoryID geçirilen CommandArgumentdeğerini olarak ayarlayınCategoryProductsDataSource.

Kategoriler Yineleyicisi için aşağıdaki ItemTemplate işaretleme, 1. ve 2. adımları uygular. Veri bağlama söz dizimi kullanılarak değere veri öğesinin CategoryID nasıl CommandArgument atandığına dikkat edin:

<ItemTemplate>
    <li>
        <asp:LinkButton CommandName="ListProducts"  runat="server"
            CommandArgument='<%# Eval("CategoryID") %>' ID="ViewCategory"
            Text='<%# string.Format("{0} ({1:N0})", _
                Eval("CategoryName"), Eval("NumberOfProducts")) %>'>
        </asp:LinkButton>
    </li>
</ItemTemplate>

Bir olay işleyicisi oluşturulduğunda, Repeater içindeki herhangi bir ItemCommand Button, LinkButton veya ImageButton tarafından tetiklenen herhangiCommandbir olay olayın tetiklenebileceğinden, her zaman ilk olarak gelen CommandName değeri denetlemek akıllıca olurItemCommand. Şu anda böyle bir LinkButton'a sahip olsak da, gelecekte Repeater'a tıklandığında aynı ItemCommand olay işleyicisini oluşturan başka düğme Web denetimleri ekleyebiliriz. Bu nedenle, özelliği her zaman denetlediğinizden CommandName emin olmak ve yalnızca beklenen değerle eşleşiyorsa programlı mantığınızla devam etmek en iyisidir.

Geçirilen CommandName değerin ListProducts değerine eşit olduğundan emin olduktan sonra, olay işleyicisi ObjectDataSource CategoryID parametresini geçirilen CommandArgumentdeğerini atarCategoryProductsDataSource. ObjectDataSource'ta yapılan bu değişiklik, DataList'in SelectParameters otomatik olarak kendisini veri kaynağına yeniden bağlamasına neden olur ve yeni seçilen kategorinin ürünlerini gösterir.

Protected Sub Categories_ItemCommand(source As Object, e As RepeaterCommandEventArgs) _
    Handles Categories.ItemCommand
    ' If it's the "ListProducts" command that has been issued...
    If String.Compare(e.CommandName, "ListProducts", True) = 0 Then
        ' Set the CategoryProductsDataSource ObjectDataSource's CategoryID parameter
        ' to the CategoryID of the category that was just clicked (e.CommandArgument)...
        CategoryProductsDataSource.SelectParameters("CategoryID").DefaultValue = _
            e.CommandArgument.ToString()
    End If
End Sub

Bu eklemelerle öğreticimiz tamamlandı! Tarayıcıda test etmek için biraz zaman ayırın. Şekil 14'te sayfayı ilk ziyaret ettiğinizde ekran gösterilir. Bir kategori henüz seçilmediğinden hiçbir ürün görüntülenmez. Ürün gibi bir kategoriye tıklanması, ürün kategorisindeki ürünleri iki sütunlu bir görünümde görüntüler (bkz. Şekil 15).

Sayfayı İlk Ziyaret Ettiğinizde Hiçbir Ürün Görüntülenmez

Şekil 14: Sayfayı İlk Ziyaret Ettiğinizde Hiçbir Ürün Görüntülenmez (Tam boyutlu resmi görüntülemek için tıklayın)

Sağda Eşleşen Ürünler Listeler Ürün Kategorisine Tıklama

Şekil 15: Sağda Eşleşen Ürünler Listeler Üretim Kategorisine tıklama (tam boyutlu görüntüyü görüntülemek için tıklayın)

Özet

Bu öğreticide ve önceki öğreticide gördüğümüz gibi, ana/ayrıntı raporları iki sayfaya yayılabilir veya bir sayfada birleştirilebilir. Ancak, bir ana/ayrıntılar raporunun tek bir sayfada görüntülenmesi, ana şablonun en iyi şekilde nasıl düzenleneceğine ilişkin bazı zorluklara neden olur ve sayfadaki kayıtların ayrıntılarını verir. Details DetailsView ile Seçilebilir Ana/Ayrıntı GridView Kullanma öğreticisinde, ayrıntılar kayıtlarının ana kayıtların üzerinde görünmesini sağlarız; Bu öğreticide, ana kayıtların ayrıntıların solunda kaydırarak olması için CSS tekniklerini kullandık.

Ana/ayrıntı raporlarını görüntülemenin yanı sıra, her kategoriyle ilişkili ürün sayısını almayı ve bir Repeater'ın içinden LinkButton (veya Düğme veya ImageButton) tıklandığında sunucu tarafı mantığının nasıl gerçekleştirildiğini keşfetme fırsatı bulduk.

Bu öğretici, DataList ve Repeater ile ana/ayrıntı raporları incelememizi tamamlar. Sonraki öğretici kümemizde DataList denetimine düzenleme ve silme özelliklerinin nasıl ekleneceği gösterilmektedir.

Mutlu Programlama!

Daha Fazla Bilgi

Bu öğreticide ele alınan konular hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın:

  • Floatutorial , CSS ile kayan CSS öğeleriyle ilgili bir öğretici
  • CSS CSS ile öğeleri konumlandırma hakkında daha fazla bilgi konumlandırma
  • Konumlandırma için s ve diğer HTML öğelerini kullanarak <table> HTML ile İçerik Yerleştirme

Yazar hakkında

Yedi ASP/ASP.NET kitabının yazarı ve 4GuysFromRolla.com kurucusu Scott Mitchell, 1998'den beri Microsoft Web teknolojileriyle çalışmaktadır. Scott bağımsız bir danışman, eğitmen ve yazar olarak çalışmaktadır. Son kitabı Sams Teach Yourself ASP.NET 24 Saat içinde 2.0. Adresine adresinden veya adresinden ulaşabileceğiniz http://ScottOnWriting.NETblogu aracılığıyla ulaşabilirsinizmitchell@4GuysFromRolla.com.

Özel Teşekkürler

Bu öğretici serisi birçok yararlı gözden geçiren tarafından gözden geçirildi. Bu öğreticinin baş gözden geçireni Zack Jones oldu. Yaklaşan MSDN makalelerimi gözden geçirmek istiyor musunuz? Öyleyse, bana bir satır mitchell@4GuysFromRolla.combırakın.