Bir Ayrıntılar DataList’i ile Madde İşaretli Ana Kayıt Listesi Kullanan Ana/Ayrıntı (C#)
tarafından Scott Mitchell
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).
Ş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.aspx
DataListRepeaterFiltering
açın ve sayfaya Repeater ve DataList ekleyin. Repeater'ı ID
olarak Categories
, DataList'i olarak CategoryProducts
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 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ı FloatLeft
iç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).
Ş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ğırarakProductsBLL
ilişkili ürünlerin sayısını belirleyebiliriz. Bu yöntem, özelliği belirtilencategoryID
için ürün sayısı olan kaçProductsRow
tane var olduğunu gösteren birProductsDataTable
nesneCount
döndürür. Repeater için, Repeater'a bağlı her kategori için sınıfınProductsBLL
GetProductsByCategoryID(categoryID)
yöntemini çağıran ve çıkıştaki sayısını içeren birItemDataBound
olay işleyicisi oluşturabiliriz. CategoriesDataTable
Yazılan Veri Kümesindeki öğesini birNumberOfProducts
sütun içerecek şekilde güncelleştirin. Daha sonra yöntemini bu bilgileri içerecek şekilde güncelleştirebilirGetCategories()
CategoriesDataTable
veya alternatif olarak olduğu gibi bırakıpGetCategories()
adlıGetCategoriesAndNumberOfProducts()
yeniCategoriesDataTable
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 ProductsBLL
GetProductsByCategoryID(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.
Ş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 ID
ViewCategory
ö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 ProductsDataTable
kaç 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 (ItemType
veya olan) çalıştığımızdan emin olup, ardından geçerli RepeaterItem
öğesine bağlı olan örneğe başvuracağızCategoriesRow
.AlternatingItem
Item
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).
Ş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'yiCategoriesDataTable
CategoriesTableAdapter
Her 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).
Ş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ı Column1
yeni bir sütun ekler. Bu yeni sütunu olarak NumberOfProducts
yeniden 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.String
System.Int32
değiştirin ve Şekil 6'da gösterildiği gibi özelliğini True
olarak ayarlayınReadOnly
.
Ş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.
Ş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)
Ş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
, CategoryName
ve 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
Ş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 NumberOfProducts
diğ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
.
Ş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 Categories
CategoriesAndProducts.aspx
bağ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).
Ş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.
Ş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``CategoryProducts
olduğ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.
Ş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 CategoryProductsDataSource
categoryID
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:
CommandName
Repeater'dakiItemTemplate
LinkButton özelliğini bir değere ayarlayın (ListProducts kullandım). BuCommandName
değeri ayarlayarak, LinkButton'aCommand
tıklandığında LinkButton olayı tetikler.- LinkButton s
CommandArgument
özelliğini geçerli öğeninCategoryID
değerine ayarlayın. - Repeater
ItemCommand
olayı için bir olay işleyicisi oluşturun. Olay işleyicisinde ObjectDataSource parametresiniCategoryID
geçirilenCommandArgument
değ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 ItemCommand
Button, 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 CommandArgument
değ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).
Ş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)
Ş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.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin