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

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ğında seçili kategorinin ürünlerini gösteren tek bir sayfaya 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ı ayrıntılar sayfasına götüren ve iki sütunlu bir DataList'in seçili kategoriye ait ürünleri gösterdiği bir köprü idi.

Bu öğreticide, iki sayfalık öğreticiyi tek bir sayfaya sıkıştıracak ve ekranın sol tarafında her kategori adının LinkButton olarak işlendiği madde işaretli kategori adlarının listesini göstereceğiz. LinkButtons kategori adından birine tıklanması geri göndermeye neden olur ve seçili kategori ü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 kaç tane toplam ürün olduğunu gösterir (bkz. Şekil 1).

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

Şekil 1: Kategori Adı ve Toplam Ürün Sayısı Solda Görüntülenir (Tam boyutlu görüntüyü 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ındaki 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 kadar tüm öğreticilerimiz konumlandırma için CSS tekniklerini kullandı. 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. Yineleyiciyi DataList öğesinin soluna doğru kayan madde işaretli kategori listesinin 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'i olarak CategoryProductsayarlayı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 kendi <div> öğesinde DataList içine alın. Bu noktadaki işaretlemeniz aşağıdakine benzer görünmelidir:

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

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

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

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

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

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

Ardından öğesini <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. Repeater'ın DataList'in solunda 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'in çevresindeki işaretleme tamamlandıktan sonra kategori verilerini Repeater denetimine bağlamaya hazırız. Bununla birlikte, Şekil 1'deki madde işaretli kategori listesinde 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 aşağıdakilerden birini yapabiliriz:

  • bu bilgileri ASP.NET sayfasının arka planda kod sınıfından belirleyin. Belirli categoryID bir nedenle s sınıfı GetProductsByCategoryID(categoryID) yöntemini çağırarak ProductsBLL ilişkili ürünlerin sayısını belirleyebiliriz. Bu yöntem, özelliği belirtilen categoryIDiçin ürün sayısı olan kaç ProductsRow tane var olduğunu gösteren bir ProductsDataTable nesne 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ıştaki sayısını içeren bir ItemDataBound olay işleyicisi oluşturabiliriz.
  • CategoriesDataTable Yazılan Veri Kümesindeki öğesini bir NumberOfProducts sütun içerecek şekilde güncelleştirin. Daha sonra 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 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 akıllı etiketi aracılığıyla adlı CategoriesDataSource yeni bir ObjectDataSource ekleyerek başlayın. Ardından, ObjectDataSource'ı CategoriesDataSource sınıfın GetCategories() yönteminden CategoriesBLL 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'ı GetCategories() sınıfın CategoriesBLL 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çili 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 altyapısı 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 geri göndermeye neden olur; geri gönderildiğinde, seçilen kategoriye ait olan ürünleri görüntülemek için DataList ObjectDataSource'un 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ü ile ortaya çıkabilecek bazı güçlüklere neden olur. Bu nedenle, bu öğreticide 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 yerine bir HyperLink denetimi veya <a> öğesi kullanarak yinelemeniz tavsiye edilir.

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

<asp:Repeater ID="Categories" runat="server" DataSourceID="CategoriesDataSource">
    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li><asp:LinkButton runat="server" ID="ViewCategory" /></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 etkinleştirilmiş olması gerekir (Yineleyici bildirim temelli söz diziminden öğesinin atıldığını EnableViewState="False" unutmayın). 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özelliği tetiklenmez.

özelliği değerine sahip LinkButton öğesinin IDViewCategory özellik kümesi yok Text . 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 GetCategoriesByProductID(categoryID) yöntemine ProductBLL çağrı yapılarak ve sonuçta ProductsDataTablekaç kayıt döndürülür belirlenerek Repeater ItemDataBound olay işleyicisinden alınabilir:

protected void Categories_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    // Make sure we're working with a data item...
    if (e.Item.ItemType == ListItemType.Item ||
        e.Item.ItemType == ListItemType.AlternatingItem)
    {
        // Reference the CategoriesRow instance bound to this RepeaterItem
        Northwind.CategoriesRow category =
            (Northwind.CategoriesRow) ((System.Data.DataRowView) e.Item.DataItem).Row;
        // Determine how many products are in this category
        NorthwindTableAdapters.ProductsTableAdapter productsAPI =
            new NorthwindTableAdapters.ProductsTableAdapter();
        int productCount =
            productsAPI.GetProductsByCategoryID(category.CategoryID).Count;
        // Reference the ViewCategory LinkButton and set its Text property
        LinkButton ViewCategory = (LinkButton)e.Item.FindControl("ViewCategory");
        ViewCategory.Text =
            string.Format("{0} ({1:N0})", category.CategoryName, productCount);
    }
}

İlk olarak bir veri öğesiyle (ItemTypeveya olan) çalıştığımızdan emin olup, ardından geçerli RepeaterItemöğesine bağlı olan örneğe başvuracağızCategoriesRow.AlternatingItemItem 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 , sıfır ondalık basamaklı bir sayı olarak biçimlendirilir.

Not

Alternatif olarak, ASP.NET sayfasının arka planda kod sınıfına bir kategori s CategoryName ve değerlerini kabul eden ve CategoryID kategorideki CategoryName ürün sayısıyla birleştirilmiş değeri döndüren bir biçimlendirme işlevi eklemiş olabilirdik (yöntemi çağrılarak GetCategoriesByProductID(categoryID) belirlendiği gibi). Böyle bir biçimlendirme işlevinin sonuçları, olay işleyici gereksinimi yerine 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 Dayalı Olarak Biçimlendirme öğreticilerine bakın.

Bu olay işleyicisini ekledikten sonra bir dakika ayırarak sayfayı bir tarayıcı üzerinden test edin. Her kategorinin madde işaretli listede nasıl listelendiğini, kategorinin adını ve kategoriyle ilişkili ürün sayısını görüntülendiğ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 görüntüyü 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, Veri Erişim Katmanı'ndaki ve CategoriesTableAdapter öğesini bu bilgileri yerel olarak içerecek şekilde ayarlayarak CategoriesDataTable bu işlemi kolaylaştırabiliriz. Bunu başarmak için, ilişkili ürünlerin sayısını tutmak için CategoriesDataTable yeni bir sütun eklemeliyiz. DataTable'a yeni sütun eklemek için, Yazılan Veri Kümesi()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 görüntüyü 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 olarak System.StringSystem.Int32 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

Şimdi bir NumberOfProducts sütuna CategoriesDataTable 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 yöntemini bu bilgileri döndürecek şekilde güncelleştirebiliriz GetCategories() . Ancak, yalnızca nadir durumlardaki kategoriler için ilişkili ürünlerin sayısını yakalamamız gerekiyorsa (örneğin, bu öğretici için), olduğu gibi gidebilir 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ı aracılığıyla 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 Northwind.CategoriesDataTable GetCategoriesAndNumberOfProducts()
{
    return Adapter.GetCategoriesAndNumberOfProducts();
}

DAL ve BLL tamamlandıktan sonra, bu verileri içindeki Repeater'a CategoriesCategoriesAndProducts.aspxbağlamaya hazırız! Olay İşleyicisinde Ürün ItemDataBound Sayısını Belirleme bölümünden Yineleyici için zaten bir ObjectDataSource oluşturduysanız, bu ObjectDataSource öğesini silin ve Repeater DataSourceID özellik ayarını kaldırın; ayrıca arka ASP.NET kod arkası sınıfında 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'ı Yöntemi Kullanacak GetCategoriesAndNumberOfProducts Şekilde Yapılandırma (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şleyici 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 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 Seçili kategori için bu ürünleri DataList'te CategoryProducts görüntülememiz gerekir.

Karşılaştığımız zorluklardan biri, DataList'in yalnızca seçili kategoriye yönelik ürünleri görüntülemesini sağlamaktır. Details DetailsView ile Seçilebilir Ana/Ayrıntı Kılavuz Görünümü Kullanma öğreticisinde, seçilen satırın ayrıntılarının aynı sayfada bir DetailsView'da görüntülendiği, satırları seçilebilen bir GridView'un nasıl oluşturulabileceğini gördük. GridView s ObjectDataSource, s GetProducts() yöntemini kullanan ProductsBLL tüm ürünler hakkında bilgi döndürürken, DetailsView s ObjectDataSource yöntemini kullanarak GetProductsByProductID(productID) seçili ürünle ilgili 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 üzerinden geçirmek CategoryID için bir köprü kullansaydık, parametre 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 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 listelenmiş olsaydı, Parametre kaynağı açılan listesini Control, ControlID değerini de veri Web denetimi olarak ID ayarlardık. Ancak Repeater'da bir SelectedValue özellik eksik olduğundan parametre kaynağı olarak kullanılamaz. Kontrol ederseniz, ControlID açılan listesinin datalist'in yalnızca bir denetimi ID``CategoryProductsolduğunu ID görürsünüz.

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

categoryID Parametresi için Parametre Kaynağı Belirtmeyin

Şekil 13: Parametre için categoryID Parametre Kaynağı Belirtmeyin (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 s RepeatColumns özelliğini 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 CategoryID tıklanan kategoriye göre ayarlamaktır. Bu iki sınamaya neden olur: 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 olayıCommand 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 iletmemiz gerekir. Böyle bir durumda LinkButton s CommandName ve CommandArgument özelliklerine bu ek bilgi atanabilir. Ardından, LinkButton öğesine tıklandığında, Command olayı tetikler (olayı yerineClick) ve olay işleyicisine ve CommandArgument özelliklerinin değerleri CommandName geçirilir.

Command Bir olay Repeater'daki bir şablonun içinden tetiklendiğinde, Repeater'ınItemCommand olayı tetiklenir ve tıklanan LinkButton 'ın (veya Düğme 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'daki ItemTemplate LinkButton özelliğini bir değere ayarlayın (ListProducts kullandım). Bu CommandName değeri ayarlayarak, 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. Değere CommandArgument veri bağlama söz dizimi kullanılarak veri öğesine CategoryID nasıl 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>

Repeater içindeki herhangi bir ItemCommandButton, LinkButton veya ImageButton tarafından tetiklenen herCommand olay olayın tetiklenebileceğinden, her olay işleyicisi oluşturulduğunda her zaman ilk olarak gelen CommandName değeri denetlemek akıllıca olurItemCommand. Şu anda böyle bir LinkButton'ımız olsa da, gelecekte biz (veya ekibimizdeki başka bir geliştirici) Repeater'a tıklandığında aynı ItemCommand olay işleyicisini oluşturan ek düğme Web denetimleri ekleyebiliriz. Bu nedenle, özelliği her zaman denetlediğinizden CommandName ve yalnızca beklenen değerle eşleşiyorsa programlı mantığınızla devam ettiğinizden emin olmak 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 kendisini veri kaynağına yeniden bağlamasına ve yeni seçilen kategoriye ait ürünleri göstermesine neden olur.

protected void Categories_ItemCommand(object source, RepeaterCommandEventArgs e)
{
    // If it's the "ListProducts" command that has been issued...
    if (string.Compare(e.CommandName, "ListProducts", true) == 0)
    {
        // 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();
    }
}

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 bu ü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 görüntüyü görüntülemek için tıklayın)

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

Şekil 15: Sağ tarafta 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ği konusunda bazı zorluklara neden olur ve sayfadaki kayıtları ayrıntılı olarak açıklar. Details DetailsView ile Seçilebilir Bir Ana Kılavuz Görünümü Kullanarak Ana/Ayrıntı Öğreticisinde, ayrıntılar kayıtlarının ana kayıtların üstünde görünmesini sağlardık; Bu öğreticide, ana kayıtların ayrıntıların solunda kaydırarak geçişini sağlamak 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.