İç İçe Veri Web Denetimleri (VB)
tarafından Scott Mitchell
Bu öğreticide, başka bir Repeater içinde iç içe yerleştirilmiş bir Repeater'ın nasıl kullanılacağını keşfedeceğiz. Örnekler, iç Repeater'ın bildirim temelli ve programlı olarak nasıl doldurulacağını gösterir.
Giriş
Şablonlar, statik HTML ve veri bağlama söz dizimine ek olarak Web denetimleri ve Kullanıcı Denetimleri de içerebilir. Bu Web denetimlerinin özellikleri bildirim temelli, veri bağlama söz dizimi yoluyla atanabilir veya uygun sunucu tarafı olay işleyicilerinde program aracılığıyla erişilebilir.
Denetimleri bir şablona ekleyerek, görünüm ve kullanıcı deneyimi özelleştirilebilir ve geliştirilebilir. Örneğin, GridView Denetimindeki TemplateFields Kullanma öğreticisinde , bir çalışanın işe alma tarihini göstermek için TemplateField'e Takvim denetimi ekleyerek GridView görünümünü özelleştirmeyi gördük; Düzenleme ve Ekleme Arabirimlerine Doğrulama Denetimleri Ekleme veVeri Değiştirme Arabirimini Özelleştirme öğreticilerinde, doğrulama denetimleri, TextBoxes, DropDownLists ve diğer Web denetimleri ekleyerek düzenleme ve ekleme arabirimlerini özelleştirmeyi gördük.
Şablonlar başka veri Web denetimleri de içerebilir. Başka bir ifadeyle, şablonlarında başka bir DataList (veya Repeater, GridView veya DetailsView vb.) içeren bir DataList'imiz olabilir. Böyle bir arabirimle ilgili zorluk, uygun verileri iç veri Web denetimine bağlamaktır. ObjectDataSource'u kullanarak bildirim temelli seçeneklerden programlı seçeneklere kadar değişen birkaç farklı yaklaşım vardır.
Bu öğreticide, başka bir Repeater içinde iç içe yerleştirilmiş bir Repeater'ın nasıl kullanılacağını keşfedeceğiz. Dış Repeater, veritabanındaki her kategori için kategorinin adını ve açıklamasını görüntüleyen bir öğe içerir. Her kategori öğesinin iç Yineleyicisi, madde işaretli listede söz konusu kategoriye ait her ürünün bilgilerini görüntüler (bkz. Şekil 1). Örneklerimizde iç Repeater'ın bildirim temelli ve programlı olarak nasıl doldurulacağı gösterilmektedir.
Şekil 1: Her Kategori ve Ürünleri Listelenir (Tam boyutlu resmi görüntülemek için tıklayın)
1. Adım: Kategori Listesini Oluşturma
İç içe veri Web denetimlerini kullanan bir sayfa oluştururken, iç içe denetim konusunda endişelenmeden en dıştaki veri Web denetimini tasarlamayı, oluşturmayı ve test etmeyi yararlı buluyorum. Bu nedenle, her kategorinin adını ve açıklamasını listeleyen sayfaya Repeater eklemek için gereken adımları izleyerek başlayalım.
Başlangıç olarak, klasördeki DataListRepeaterBasics
sayfayı NestedControls.aspx
açın ve sayfaya bir Repeater denetimi ekleyerek özelliğini olarak CategoryList
ayarlayınID
. Repeater'ın akıllı etiketinden adlı CategoriesDataSource
yeni bir ObjectDataSource oluşturmayı seçin.
Şekil 2: Yeni ObjectDataSource CategoriesDataSource
adını verin (Tam boyutlu görüntüyü görüntülemek için tıklayın)
ObjectDataSource'u sınıfın CategoriesBLL
GetCategories
yönteminden verilerini çekecek şekilde yapılandırın.
Şekil 3: ObjectDataSource'ı Sınıf GetCategories
Yöntemini Kullanacak CategoriesBLL
Şekilde Yapılandırma (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Repeater şablonu içeriğini belirtmek için Kaynak görünümüne gidip bildirim temelli söz dizimini el ile girmemiz gerekir. Bir ItemTemplate
öğede kategori adını ve paragraf <h4>
öğesinde (<p>
) kategori açıklamasını görüntüleyen bir ekleyin. Ayrıca, her kategoriyi yatay bir kuralla (<hr>
) ayıralım. Bu değişiklikleri yaptıktan sonra sayfanız Repeater ve ObjectDataSource için aşağıdakine benzer bildirim temelli söz dizimi içermelidir:
<asp:Repeater ID="CategoryList" DataSourceID="CategoriesDataSource"
EnableViewState="False" runat="server">
<ItemTemplate>
<h4><%# Eval("CategoryName") %></h4>
<p><%# Eval("Description") %></p>
</ItemTemplate>
<SeparatorTemplate>
<hr />
</SeparatorTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
Şekil 4'de tarayıcı üzerinden görüntülendiğinde ilerleme durumumuz gösterilmektedir.
Şekil 4: Her Kategorinin Adı ve Açıklaması Yatay Bir Kuralla Ayrılmış Olarak Listelenir (Tam boyutlu resmi görüntülemek için tıklayın)
2. Adım: İç İçe Ürün Yineleyicisini Ekleme
Kategori listesi tamamlandıktan sonra, bir sonraki görevimiz, uygun kategoriye CategoryList
ait ürünlerle ilgili bilgileri görüntüleyen bir ItemTemplate
Repeater eklemektir. Bu iç Repeater'ın verilerini almanın birkaç yolu vardır; bunlardan ikisi de kısa bir süre içinde incelenir. Şimdilik Repeater'ın ItemTemplate
içinde CategoryList
Repeater ürünlerini oluşturalım. Özellikle, repeater ürününün her ürünü, ürün adı ve fiyatı dahil olmak üzere her liste öğesiyle birlikte madde işaretli bir listede görüntülemesini sağlayın.
Bu Repeater'ı oluşturmak için iç Repeater'ın bildirim temelli söz dizimini ve şablonlarını s ItemTemplate
içine CategoryList
el ile girmemiz gerekir. Repeater'ın ItemTemplate
içine aşağıdaki işaretlemeyi CategoryList
ekleyin:
<asp:Repeater ID="ProductsByCategoryList" EnableViewState="False"
runat="server">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><strong><%# Eval("ProductName") %></strong>
(<%# Eval("UnitPrice", "{0:C}") %>)</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
3. Adım: Category-Specific Ürünlerini ProductsByCategoryList Repeater'a Bağlama
Bu noktada sayfayı bir tarayıcı üzerinden ziyaret ederseniz, yineleyiciye henüz veri bağlamadığımız için ekranınız Şekil 4'tekiyle aynı görünür. Uygun ürün kayıtlarını alıp Repeater'a bağlamanın birkaç yolu vardır; bazıları diğerlerinden daha verimlidir. Buradaki temel zorluk, belirtilen kategori için uygun ürünleri geri almaktır.
İç Repeater denetimine bağlanacak verilere Repeater'ın ItemTemplate
içindeki bir ObjectDataSource CategoryList
aracılığıyla bildirim temelli olarak veya program aracılığıyla, ASP.NET sayfasının arkadaki kod sayfasından erişilebilir. Benzer şekilde, bu veriler iç Repeater özelliği aracılığıyla veya bildirim temelli veri bağlama söz dizimi aracılığıyla veya Repeater'ın DataSourceID
olay işleyicisindeki CategoryList
iç Repeater'a başvurarak, özelliğini program aracılığıyla ayarlayarak DataSource
ve yöntemini çağırarak DataBind()
bildirim temelli olarak iç Repeater'a ItemDataBound
bağlanabilir. Şimdi bu yaklaşımların her birini inceleyelim.
ObjectDataSource Denetimi veItemDataBound
Olay İşleyicisi ile Verilere Bildirimli Olarak Erişme
Bu öğretici serisi boyunca ObjectDataSource'u yoğun bir şekilde kullandığımızdan, bu örnekteki verilere erişmek için en doğal seçenek ObjectDataSource'a bağlı kalmaktır. sınıfı, ProductsBLL
belirtilen categoryID
öğesine ait olan ürünler hakkında bilgi döndüren bir GetProductsByCategoryID(categoryID)
yöntemine sahiptir. Bu nedenle Repeater'lara CategoryList
ItemTemplate
bir ObjectDataSource ekleyebilir ve bu sınıfın yönteminden verilerine erişecek şekilde yapılandırabiliriz.
Ne yazık ki Repeater şablonlarının Tasarım görünümü aracılığıyla düzenlenmesine izin vermez, bu nedenle bu ObjectDataSource denetimi için bildirim temelli söz dizimini el ile eklememiz gerekir. Aşağıdaki söz diziminde, bu yeni ObjectDataSource (ProductsByCategoryDataSource
eklendikten sonra Repeater'lar ItemTemplate
gösterilirCategoryList
):
<h4><%# Eval("CategoryName") %></h4>
<p><%# Eval("Description") %></p>
<asp:Repeater ID="ProductsByCategoryList" EnableViewState="False"
DataSourceID="ProductsByCategoryDataSource" runat="server">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><strong><%# Eval("ProductName") %></strong> -
sold as <%# Eval("QuantityPerUnit") %> at
<%# Eval("UnitPrice", "{0:C}") %></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ProductsByCategoryDataSource" runat="server"
SelectMethod="GetProductsByCategoryID" TypeName="ProductsBLL">
<SelectParameters>
<asp:Parameter Name="CategoryID" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
ObjectDataSource yaklaşımını kullanırken Repeater s DataSourceID
özelliğini ObjectDataSource ()ProductsByCategoryDataSource
değerine ID
ayarlamamız ProductsByCategoryList
gerekir. Ayrıca, ObjectDataSource'umuzun yöntemine categoryID
GetProductsByCategoryID(categoryID)
geçirilecek değeri belirten bir <asp:Parameter>
öğesi olduğuna dikkat edin. Peki bu değeri nasıl belirteceğiz? İdeal olarak, databinding söz dizimini DefaultValue
kullanarak öğesinin <asp:Parameter>
özelliğini ayarlayabiliriz, örneğin:
<asp:Parameter Name="CategoryID" Type="Int32"
DefaultValue='<%# Eval("CategoryID")' />
Ne yazık ki, veri bağlama söz dizimi yalnızca olay DataBinding
içeren denetimlerde geçerlidir. Sınıfında Parameter
böyle bir olay olmadığından yukarıdaki söz dizimi geçersizdir ve çalışma zamanı hatasına neden olur.
Bu değeri ayarlamak için Repeater ItemDataBound
olayı için bir olay işleyicisi CategoryList
oluşturmamız gerekir. Olayın Repeater'a ItemDataBound
bağlı her öğe için bir kez tetiklendiğini hatırlayın. Bu nedenle, bu olay dış Repeater için her tetiklendiğinde geçerli CategoryID
değeri ObjectDataSource CategoryID
parametresine ProductsByCategoryDataSource
atayabiliriz.
Repeater ItemDataBound
olayı için CategoryList
aşağıdaki kodla bir olay işleyicisi oluşturun:
Protected Sub CategoryList_ItemDataBound(sender As Object, e As RepeaterItemEventArgs) _
Handles CategoryList.ItemDataBound
If e.Item.ItemType = ListItemType.AlternatingItem _
OrElse e.Item.ItemType = ListItemType.Item Then
' Reference the CategoriesRow object being bound to this RepeaterItem
Dim category As Northwind.CategoriesRow = _
CType(CType(e.Item.DataItem, System.Data.DataRowView).Row, _
Northwind.CategoriesRow)
' Reference the ProductsByCategoryDataSource ObjectDataSource
Dim ProductsByCategoryDataSource As ObjectDataSource = _
CType(e.Item.FindControl("ProductsByCategoryDataSource"), _
ObjectDataSource)
' Set the CategoryID Parameter value
ProductsByCategoryDataSource.SelectParameters("CategoryID").DefaultValue = _
category.CategoryID.ToString()
End If
End Sub
Bu olay işleyicisi, üst bilgi, alt bilgi veya ayırıcı öğe yerine bir veri öğesiyle ilgilenmemizi sağlayarak başlar. Ardından, geçerli RepeaterItem
öğesine bağlı olan gerçek CategoriesRow
örneğe başvuracağız. Son olarak içindeki ObjectDataSource öğesine ItemTemplate
başvuruyoruz ve parametre değerini CategoryID
geçerli RepeaterItem
öğesine atıyoruzCategoryID
.
Bu olay işleyicisiyle, her RepeaterItem
birindeki ProductsByCategoryList
Repeater, s kategorisindeki RepeaterItem
ürünlere bağlıdır. Şekil 5'de, sonuçta elde edilen çıkışın ekran görüntüsü gösterilir.
Şekil 5: Dış Yineleyici Her Kategoriyi Listeler; İç Yineleme söz konusu Kategori için Ürünler'i Listeler (tam boyutlu görüntüyü görüntülemek için tıklayın)
Kategori Verilerine Göre Ürünlere Program Aracılığıyla Erişme
Geçerli kategoriye ait ürünleri almak için Bir ObjectDataSource kullanmak yerine, ASP.NET sayfamızın arka planda kod sınıfında (veya klasöründe veya ayrı bir Sınıf Kitaplığı projesinde App_Code
) geçirildiğinde uygun ürün kümesini döndüren bir CategoryID
yöntem oluşturabiliriz. ASP.NET sayfamızın arka planda kod sınıfında böyle bir yöntemimiz olduğunu ve olarak adlandırıldığını GetProductsInCategory(categoryID)
düşünün. Bu yöntem kullanıldığında, aşağıdaki bildirim temelli söz dizimini kullanarak geçerli kategoriye ilişkin ürünleri iç Repeater'a bağlayabiliriz:
<asp:Repeater runat="server" ID="ProductsByCategoryList" EnableViewState="False"
DataSource='<%# GetProductsInCategory(CType(Eval("CategoryID"), Integer)) %>'>
...
</asp:Repeater>
Repeater özelliği DataSource
, verilerinin yönteminden geldiğini belirtmek için veri bağlama söz dizimini GetProductsInCategory(categoryID)
kullanır. Eval("CategoryID")
türünde Object
bir değer döndürdüğünden, yöntemine geçirmeden önce nesnesini öğesine Integer
yayınlarızGetProductsInCategory(categoryID)
. CategoryID
Burada veri bağlama söz dizimi CategoryID
aracılığıyla erişilen öğesinin, tablodaki kayıtlara bağlı olan dış Repeater ()CategoryList
içinde Categories
olduğunu unutmayın. Bu nedenle, bir veritabanı değeri olamayacağını CategoryID
biliyoruz, bu nedenle bir ile DBNull
ilgilenip ilgilenmediğimize denetlemeden yöntemi kör bir şekilde yayınlayabilirizEval
.NULL
Bu yaklaşımla yöntemini oluşturmamız GetProductsInCategory(categoryID)
ve sağlanan categoryID
verilen ürün kümesini almasını sağlamalıyız. Bunu yapmak için sınıfın ProductsDataTable
GetProductsByCategoryID(categoryID)
yöntemi tarafından döndürülen öğesini ProductsBLL
döndürebiliriz. Sayfamız NestedControls.aspx
için arka planda kod sınıfında yöntemini oluşturalımGetProductsInCategory(categoryID)
. Bunu aşağıdaki kodu kullanarak yapın:
Protected Function GetProductsInCategory(ByVal categoryID As Integer) _
As Northwind.ProductsDataTable
' Create an instance of the ProductsBLL class
Dim productAPI As ProductsBLL = New ProductsBLL()
' Return the products in the category
Return productAPI.GetProductsByCategoryID(categoryID)
End Function
Bu yöntem yalnızca yönteminin bir örneğini ProductsBLL
oluşturur ve yönteminin GetProductsByCategoryID(categoryID)
sonuçlarını döndürür. yönteminin veya Protected
olarak işaretlenmesi Public
gerektiğini unutmayın; yöntem olarak işaretlenmişsePrivate
, ASP.NET sayfasının bildirim temelli işaretlemesinden erişilemez.
Bu yeni tekniği kullanmak için bu değişiklikleri yaptıktan sonra, sayfayı bir tarayıcı üzerinden görüntülemek için biraz zaman ayırın. ObjectDataSource ve ItemDataBound
olay işleyicisi yaklaşımı kullanılırken çıktı çıktıyla aynı olmalıdır (ekran görüntüsünü görmek için Şekil 5'e geri bakın).
Not
ASP.NET sayfasının arka planda kod sınıfında yöntemini oluşturmak GetProductsInCategory(categoryID)
meşgul gibi görünebilir. Sonuçta, bu yöntem yalnızca sınıfının bir örneğini ProductsBLL
oluşturur ve yönteminin GetProductsByCategoryID(categoryID)
sonuçlarını döndürür. Neden bu yöntemi doğrudan iç Repeater'daki veri bağlama söz diziminden çağırmıyor, örneğin: DataSource='<%# ProductsBLL.GetProductsByCategoryID(CType(Eval("CategoryID"), Integer)) %>'
? Bu söz dizimi geçerli sınıf uygulamamızla ProductsBLL
çalışmasa da (yöntem bir örnek yöntemi olduğundanGetProductsByCategoryID(categoryID)
), statik GetProductsByCategoryID(categoryID)
bir yöntem içerecek şekilde değiştirebilir ProductsBLL
veya sınıfın sınıfının yeni bir örneğini döndürmek için statik Instance()
bir yöntem içermesini ProductsBLL
sağlayabilirsiniz.
Bu tür değişiklikler, ASP.NET sayfasının arka kod arkası sınıfında yöntemine GetProductsInCategory(categoryID)
olan ihtiyacı ortadan kaldırsa da arka planda kod yöntemi, kısa süre içinde göreceğimiz gibi alınan verilerle çalışma konusunda bize daha fazla esneklik sağlar.
Tüm Ürün Bilgilerini Aynı Anda Alma
İncelediğimiz iki pervious teknik, sınıfın GetProductsByCategoryID(categoryID)
yöntemine ProductsBLL
bir çağrı yaparak geçerli kategori için bu ürünleri alır (ilk yaklaşım bir ObjectDataSource aracılığıyla, ikinci yaklaşım ise arkadaki kod sınıfındaki yöntemi aracılığıyla GetProductsInCategory(categoryID)
bunu yapmıştır). Bu yöntem her çağrıldığında İş Mantığı Katmanı Veri Erişim Katmanı'nı çağırır. Bu katman, alanı sağlanan giriş parametresiyle eşleşen tablodan Products
satırlar döndüren CategoryID
bir SQL deyimiyle veritabanını sorgular.
Sistemdeki N kategorileri göz önünde bulundurulduğunda bu yaklaşım, tüm kategorileri almak için veritabanına bir veritabanı sorgusu ve her kategoriye özgü ürünleri almak için N çağrıları ağlarına ekler. Ancak, tüm kategorileri almak için bir çağrı ve tüm ürünleri almak için diğerini almak için yalnızca iki veritabanı çağrısında gerekli tüm verileri alacağız. Tüm ürünlere sahip olduktan sonra, bu ürünleri filtreleyebiliriz, böylece yalnızca güncel CategoryID
ürünle eşleşen ürünler bu kategorinin iç Repeater'sine bağlıdır.
Bu işlevselliği sağlamak için, ASP.NET sayfamızın arka planda kod sınıfındaki yönteminde küçük bir değişiklik GetProductsInCategory(categoryID)
yapmamız yeterlidir. Sınıf yönteminin ProductsBLL
sonuçlarını körü körüne döndürmek yerine, bunun yerine önce tüm ürünlere erişebilir (henüz erişilmemişse) ve ardından geçirilen CategoryID
öğesine göre ürünlerin yalnızca filtrelenmiş görünümünü döndürebiliriz.GetProductsByCategoryID(categoryID)
Private allProducts As Northwind.ProductsDataTable = Nothing
Protected Function GetProductsInCategory(ByVal categoryID As Integer) _
As Northwind.ProductsDataTable
' First, see if we've yet to have accessed all of the product information
If allProducts Is Nothing Then
Dim productAPI As ProductsBLL = New ProductsBLL()
allProducts = productAPI.GetProducts()
End If
' Return the filtered view
allProducts.DefaultView.RowFilter = "CategoryID = " & categoryID
Return allProducts
End Function
Sayfa düzeyi değişkeninin eklenmesine dikkat edin: allProducts
. Bu, tüm ürünlerle ilgili bilgileri tutar ve yöntem ilk kez GetProductsInCategory(categoryID)
çağrıldığında doldurulur. Nesnenin allProducts
oluşturulduğundan ve dolduruldığından emin olduktan sonra yöntemi DataTable sonuçlarını yalnızca belirtilen CategoryID
satırlarla eşleşen satırların CategoryID
erişilebilir olmasını sağlayacak şekilde filtreler. Bu yaklaşım, veritabanına N + 1'den ikiye kadar erişim sayısını azaltır.
Bu geliştirme, sayfanın işlenmiş işaretlemesinde herhangi bir değişiklik yapmaz ve diğer yaklaşımdan daha az kayıt getirmez. Yalnızca veritabanına yapılan çağrı sayısını azaltır.
Not
Veritabanı erişimlerinin sayısının azaltılmasının performansı kesinlikle artıracağı konusunda sezgisel bir neden olabilir. Ancak, durum böyle olmayabilir. Örneğin, olan CategoryID
NULL
çok sayıda ürününüz varsa, yöntemine GetProducts
yapılan çağrı hiçbir zaman görüntülenmeyen bir dizi ürün döndürür. Ayrıca, kategorilerin yalnızca bir alt kümesini gösteriyorsanız, tüm ürünlerin iade edilmesi boşa gidebilir ve disk belleği uyguladıysanız bu durum söz konusu olabilir.
Her zaman olduğu gibi, iki tekniğin performansını analiz etmek söz konusu olduğunda, tek kesin sonuç ölçüsü uygulamanızın yaygın durum senaryoları için uyarlanmış denetimli testler çalıştırmaktır.
Özet
Bu öğreticide, özellikle bir dış Repeater'ın madde işaretli bir listede her kategoriye ait ürünleri listeleyen bir iç Repeater ile her kategori için bir öğe görüntülemesini inceleme amacıyla bir veri Web denetimini başka bir verinin içine nasıl yerleştirebileceğimizi gördük. İç içe kullanıcı arabirimi oluşturmanın temel zorluğu, doğru verilere erişmek ve iç veri Web denetimine bağlamaktır. Bu öğreticide incelediğimiz çeşitli teknikler vardır. İncelenen ilk yaklaşım, dış veri Web denetiminde, özelliği aracılığıyla DataSourceID
iç veri Web denetimine ItemTemplate
bağlı olan bir ObjectDataSource kullandı. İkinci teknik, ASP.NET sayfasının arkadaki kod sınıfındaki bir yöntem aracılığıyla verilere erişildi. Bu yöntem daha sonra veri bağlama söz dizimi aracılığıyla iç veri Web denetimi DataSource
özelliğine bağlanabilir.
Bu öğreticide incelenen iç içe kullanıcı arabirimi bir Repeater içinde iç içe bir Repeater kullansa da, bu teknikler diğer veri Web denetimlerine genişletilebilir. Bir Repeater'ı GridView içine veya GridView'u DataList içinde iç içe yerleştirebilirsiniz, vb.
Mutlu Programlama!
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 Hours 2.0'dır. 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çirenleri Zack Jones ve Liz Shulok'tur. Yaklaşan MSDN makalelerimi gözden geçirmek istiyor musunuz? Öyleyse, bana adresinden 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