Özelleştirilmiş Sıralama Kullanıcı Arabirimi Oluşturma (C#)Creating a Customized Sorting User Interface (C#)

Scott Mitchell tarafındanby Scott Mitchell

Örnek uygulamayı indirin veya PDF 'yi indirinDownload Sample App or Download PDF

Sıralanmış verilerin uzun bir listesini görüntülerken, ayırıcı satırlara bakarak ilgili verileri gruplamak çok faydalı olabilir.When displaying a long list of sorted data, it can be very helpful to group related data by introducing separator rows. Bu öğreticide, böyle bir sıralama Kullanıcı arabirimi oluşturma hakkında bilgi edineceksiniz.In this tutorial we'll see how to create such a sorting user interface.

GirişIntroduction

Sıralanmış sütunda yalnızca birkaç farklı değerin bulunduğu bir veri sıralanmış verilerin uzun bir listesini görüntülerken, Son Kullanıcı tam olarak fark sınırlarının meydana gelir.When displaying a long list of sorted data where there are only a handful of different values in the sorted column, an end user might find it hard to discern where, exactly, the difference boundaries occur. Örneğin, veritabanında 81 ürün vardır, ancak yalnızca dokuz farklı kategori seçeneği vardır (sekiz benzersiz kategori ve NULL seçeneği).For example, there are 81 products in the database, but only nine different category choices (eight unique categories plus the NULL option). Deniz yiyecek kategorisi kapsamında yer alan ürünleri incelemek isteyen bir kullanıcının durumunu göz önünde bulundurun.Consider the case of a user who is interested in examining the products that fall under the Seafood category. Tek bir GridView 'daki Tüm ürünleri listeleyen bir sayfadan, Kullanıcı en iyi sonuçları kategoriye göre sıralamak ve bu da tüm deniz yiyecek ürünlerini birlikte gruplamak için karar verebilir.From a page that lists all of the products in a single GridView, the user might decide her best bet is to sort the results by category, which will group together all of the Seafood products together. Kategoriye göre sıraladıktan sonra, kullanıcının, deniz yiyecek tarafından gruplanmış ürünlerin nerede başlayıp bitebileceği konusunda arama yapması gerekir.After sorting by category, the user then needs to hunt through the list, looking for where the Seafood-grouped products start and end. Sonuçlar kategori adına göre alfabetik olarak sıralandığından, deniz yiyecek ürünlerini bulma zor değildir, ancak yine de kılavuzdaki öğelerin listesini yakından taramak istiyor.Since the results are ordered alphabetically by the category name finding the Seafood products is not difficult, but it still requires closely scanning the list of items in the grid.

Sıralanmış gruplar arasındaki sınırları vurgulamada yardımcı olması için birçok Web sitesi bu gruplar arasında bir ayırıcı ekleyen bir kullanıcı arabirimi sağlar.To help highlight the boundaries between sorted groups, many websites employ a user interface that adds a separator between such groups. Şekil 1 ' de gösterilenler gibi ayırıcılar, bir kullanıcının belirli bir grubu daha hızlı bulmasına ve sınırlarını tanımlamasına olanak sağlar ve verilerde farklı grupların mevcut olduğunu belirlemektir.Separators like the ones shown in Figure 1 enables a user to more quickly find a particular group and identify its boundaries, as well as ascertain what distinct groups exist in the data.

Her kategori grubu açıkça tanımlanmış Each Category Group is Clearly Identified

Şekil 1: her kategori grubu açıkça tanımlanır (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 1: Each Category Group is Clearly Identified (Click to view full-size image)

Bu öğreticide, böyle bir sıralama Kullanıcı arabirimi oluşturma hakkında bilgi edineceksiniz.In this tutorial we'll see how to create such a sorting user interface.

1. Adım: Standart, sıralanabilir bir GridView oluşturmaStep 1: Creating a Standard, Sortable GridView

Gelişmiş sıralama arabirimini sağlamak için GridView 'un nasıl geliştiğini araştırmadan önce, ilk olarak ürünleri listeleyen standart, sıralanabilir bir GridView oluşturmaya izin verin.Before we explore how to augment the GridView to provide the enhanced sorting interface, let s first create a standard, sortable GridView that lists the products. PagingAndSorting klasöründeki CustomSortingUI.aspx sayfasını açarak başlayın.Start by opening the CustomSortingUI.aspx page in the PagingAndSorting folder. Sayfaya bir GridView ekleyin, ID özelliğini ProductListolarak ayarlayın ve yeni bir ObjectDataSource 'a bağlayın.Add a GridView to the page, set its ID property to ProductList, and bind it to a new ObjectDataSource. ObjectDataSource, kayıt seçmek için ProductsBLL sınıf s GetProducts() metodunu kullanacak şekilde yapılandırın.Configure the ObjectDataSource to use the ProductsBLL class s GetProducts() method for selecting records.

Daha sonra, GridView 'u yalnızca ProductName, CategoryName, SupplierNameve UnitPrice BoundFields ve Discontinued CheckBoxField 'ı içermesi için yapılandırın.Next, configure the GridView such that it only contains the ProductName, CategoryName, SupplierName, and UnitPrice BoundFields and the Discontinued CheckBoxField. Son olarak, GridView 'u akıllı etiketteki sıralamayı etkinleştir onay kutusunu işaretleyerek (veya AllowSorting özelliğini trueolarak ayarlayarak) sıralamayı destekleyecek şekilde yapılandırın.Finally, configure the GridView to support sorting by checking the Enable Sorting checkbox in the GridView s smart tag (or by setting its AllowSorting property to true). Bu eklemeleri CustomSortingUI.aspx sayfasına yaptıktan sonra, bildirime dayalı biçimlendirme aşağıdakine benzer şekilde görünmelidir:After making these additions to the CustomSortingUI.aspx page, the declarative markup should look similar to the following:

<asp:GridView ID="ProductList" runat="server" AllowSorting="True"
    AutoGenerateColumns="False" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category"
            ReadOnly="True" SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName" HeaderText="Supplier"
            ReadOnly="True" SortExpression="SupplierName" />
        <asp:BoundField DataField="UnitPrice" DataFormatString="{0:C}"
            HeaderText="Price" HtmlEncode="False" SortExpression="UnitPrice" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
    TypeName="ProductsBLL"></asp:ObjectDataSource>

Sürmekte olan ilerimizi bir tarayıcıda görüntülemek için bir dakikanızı ayırın.Take a moment to view our progress thus far in a browser. Şekil 2, verileri kategoriye göre alfabetik sırada sıralandığında sıralanabilir GridView 'ı gösterir.Figure 2 shows the sortable GridView when its data is sorted by category in alphabetical order.

Sıralanabilir GridView s verileri kategoriye göre sıralanmıştır The Sortable GridView s Data is Ordered by Category

Şekil 2: sıralanabilir GridView s verileri kategoriye göre sıralanır (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 2: The Sortable GridView s Data is Ordered by Category (Click to view full-size image)

2. Adım: ayırıcı satırları ekleme tekniklerini keşfetmeStep 2: Exploring Techniques for Adding the Separator Rows

Genel, sıralanabilir GridView tamamlandığına göre, her bir benzersiz sıralı gruptan önce GridView 'da ayırıcı satırları ekleyebileceksiniz.With the generic, sortable GridView complete, all that remains is to be able to add the separator rows in the GridView before each unique sorted group. Ancak bu satırlar GridView 'a nasıl eklenebilir?But how can such rows be injected into the GridView? Temel olarak, GridView s satırlarını yineliyoruz, sıralanan sütundaki değerler arasında farklılıkların nerede gerçekleşeceğini saptamalıdır ve ardından uygun ayırıcı satırı eklersiniz.Essentially, we need to iterate through the GridView s rows, determine where the differences occur between the values in the sorted column, and then add the appropriate separator row. Bu sorunu düşünürken, çözümün GridView s RowDataBound olay işleyicisinde bir yerde yer aldığı doğal görünür.When thinking about this problem, it seems natural that the solution lies somewhere in the GridView s RowDataBound event handler. Veri öğreticisini temel alan özel biçimlendirme bölümünde anlatıldığı gibi, bu olay işleyicisi genellikle satır s verilerine göre satır düzeyinde biçimlendirme uygulanırken kullanılır.As we discussed in the Custom Formatting Based Upon Data tutorial, this event handler is commonly used when applying row-level formatting based on the row s data. Ancak, bu olay işleyicisinden program aracılığıyla GridView 'a eklenemediğinden RowDataBound olay işleyicisi burada çözüm değildir.However, the RowDataBound event handler is not the solution here, as rows cannot be added to the GridView programmatically from this event handler. GridView s Rows koleksiyonu, aslında salt okunurdur.The GridView s Rows collection, in fact, is read-only.

GridView 'a ek satırlar eklemek için üç seçenek vardır:To add additional rows to the GridView we have three choices:

  • Bu meta veri ayırıcı satırlarını GridView 'a bağlanan gerçek verilere ekleyinAdd these metadata separator rows to the actual data that is bound to the GridView
  • GridView verileri bağladıktan sonra, GridView s denetim koleksiyonuna ek TableRow örnekleri ekleyinAfter the GridView has been bound to the data, add additional TableRow instances to the GridView s control collection
  • GridView denetimini genişleten ve GridView s yapısını oluşturmaktan sorumlu bu yöntemleri geçersiz kılan özel bir sunucu denetimi oluşturunCreate a custom server control that extends the GridView control and overrides those methods responsible for constructing the GridView s structure

Bu işlevsellik birçok Web sayfasında veya birkaç Web sitesinde gerekliyse, özel sunucu denetimi oluşturmak en iyi yaklaşım olacaktır.Creating a custom server control would be the best approach if this functionality was needed on many web pages or across several websites. Ancak, tam olarak bir kod ve GridView 'un iç işleyişi derinliklerinde tam bir keşif yapılır.However, it would entail quite a bit of code and a thorough exploration into the depths of the GridView s internal workings. Bu nedenle bu seçeneği bu öğreticide kabul eteceğiz.Therefore, we'll not consider that option for this tutorial.

Diğer iki seçenek de, GridView 'a bağlanacak gerçek verilere ayırıcı satırları ekleme ve GridView s denetim koleksiyonunu bağladıktan sonra düzenleme-bir tartışmayı farklı haleThe other two options adding separator rows to the actual data being bound to the GridView and manipulating the GridView s control collection after its been bound - attack the problem differently and merit a discussion.

GridView 'a bağlantılı verilere satır eklemeAdding Rows to the Data Bound to the GridView

GridView bir veri kaynağına bağlandığında, veri kaynağı tarafından döndürülen her kayıt için bir GridViewRow oluşturur.When the GridView is bound to a data source, it creates a GridViewRow for each record returned by the data source. Bu nedenle, GridView 'a bağlamadan önce veri kaynağına ayırıcı kayıtlar ekleyerek gerekli ayırıcı satırları ekleyebiliriz.Therefore, we can inject the needed separator rows by adding separator records to the data source before binding it to the GridView. Şekil 3 ' te bu kavram gösterilmektedir.Figure 3 illustrates this concept.

Bir teknik, veri kaynağına ayırıcı satırları eklemeyi Içerir

Şekil 3: bir teknik, veri kaynağına ayırıcı satırları eklemeyi içerirFigure 3: One Technique Involves Adding Separator Rows to the Data Source

Özel bir ayırıcı kaydı olmadığından, ayırıcı kayıtları tırnak içinde kullanıyorum; Bunun yerine, veri kaynağındaki belirli bir kaydın normal bir veri satırı yerine bir ayırıcı görevi gören bir şekilde bayrak atamamız gerekir.I use the term separator records in quotes because there is no special separator record; rather, we must somehow flag that a particular record in the data source serves as a separator rather than a normal data row. Örneklerimizde, ProductRowsoluşan GridView 'a ProductsDataTable bir örnek bağlamamız gerekir.For our examples, we re binding a ProductsDataTable instance to the GridView, which is composed of ProductRows. CategoryID özelliğini -1 olarak ayarlayarak (böyle bir değer normal olarak bulunmadığından) bir kaydı ayırıcı satır olarak bayrakla işaretliyoruz.We might flag a record as a separator row by setting its CategoryID property to -1 (since such a value couldn't exist normally).

Bu tekniği kullanmak için aşağıdaki adımları gerçekleştirmeniz gerekir:To utilize this technique we d need to perform the following steps:

  1. GridView 'a bağlanacak verileri program aracılığıyla alma (bir ProductsDataTable örneği)Programmatically retrieve the data to bind to the GridView (a ProductsDataTable instance)
  2. GridView s SortExpression ve SortDirection özelliklerine göre verileri sıralayınSort the data based on the GridView s SortExpression and SortDirection properties
  3. Sıralanmış sütundaki farkların nerede olduğunu arayarak ProductsDataTable``ProductsRows yineleyinIterate through the ProductsRows in the ProductsDataTable, looking for where the differences in the sorted column lie
  4. Her grup sınırında, DataTable 'a ProductsRow bir ayırıcı kaydı ekleyin, bu CategoryID -1 olarak ayarlanmıştır (veya bir kaydı bir ayırıcı kayıt olarak işaretlemek için herhangi bir atama olduğuna karar verdi)At each group boundary, inject a separator record ProductsRow instance into the DataTable, one that has it s CategoryID set to -1 (or whatever designation was decided upon to mark a record as a separator record )
  5. Ayırıcı satırları ekleme sonra programlı olarak verileri GridView 'a bağlayınAfter injecting the separator rows, programmatically bind the data to the GridView

Bu beş adıma ek olarak, GridView s RowDataBound olayı için de bir olay işleyicisi sağlamanız gerekir.In addition to these five steps, we d also need to provide an event handler for the GridView s RowDataBound event. Burada her bir DataRow denetliyoruz ve CategoryID ayarı -1olan bir ayırıcı satır olup olmadığını saptadık.Here, we d check each DataRow and determine if it was a separator row, one whose CategoryID setting was -1. Öyleyse, büyük olasılıkla biçimini veya hücrede görüntülenecek metni ayarlamak istiyoruz.If so, we d probably want to adjust its formatting or the text displayed in the cell(s).

Ekleme için bu tekniği kullanarak sıralama grubu sınırları, GridView s Sorting olayına bir olay işleyicisi sağlamanız ve SortExpression ve SortDirection değerlerinin izlenmesini sağlamak için yukarıda özetlenen bir daha fazla iş gerektirir.Using this technique for injecting the sorting group boundaries requires a bit more work than outlined above, as you need to also provide an event handler for the GridView s Sorting event and keep track of the SortExpression and SortDirection values.

GridView s denetim koleksiyonunu, veri sınırına geçtikten sonra düzenlemeManipulating the GridView s Control Collection After It s Been Databound

GridView 'a bağlamadan önce verileri mesajlaşma yerine, veri GridView 'a bağlandıktan sonra ayırıcı satırları ekleyebiliriz.Rather than messaging the data before binding it to the GridView, we can add the separator rows after the data has been bound to the GridView. Veri bağlama işlemi, her biri bir hücre koleksiyonundan oluşan bir satır koleksiyonundan oluşan Table bir örnek olan GridView s denetim hiyerarşisini oluşturur.The process of data binding builds up the GridView s control hierarchy, which in reality is simply a Table instance composed of a collection of rows, each of which is composed of a collection of cells. Özellikle, GridView s denetim koleksiyonu, kendi kökünde bir Table nesnesi, GridView öğesine göre DataSource her bir kayıt için bir GridViewRow (TableRow sınıfından türetilir) ve TableCell her veri alanı için her GridViewRow örneğindeki bir DataSourcenesnesi içerir.Specifically, the GridView s control collection contains a Table object at its root, a GridViewRow (which is derived from the TableRow class) for each record in the DataSource bound to the GridView, and a TableCell object in each GridViewRow instance for each data field in the DataSource.

Her sıralama grubu arasına ayırıcı satırlar eklemek için, oluşturulduktan sonra bu denetim hiyerarşisini doğrudan işleyebiliriz.To add separator rows between each sorting group, we can directly manipulate this control hierarchy once it has been created. GridView s denetim hiyerarşisinin, sayfanın işlendiği zamana göre son kez oluşturulduğundan emin olabilirsiniz.We can be confident that the GridView s control hierarchy has been created for the last time by the time the page is being rendered. Bu nedenle, bu yaklaşım Page sınıf s Render yöntemini geçersiz kılar, bu noktada GridView s son denetim hiyerarşisi gereken ayırıcı satırları içerecek şekilde güncelleştirilir.Therefore, this approach overrides the Page class s Render method, at which point the GridView s final control hierarchy is updated to include the needed separator rows. Şekil 4 ' te bu işlem gösterilmektedir.Figure 4 illustrates this process.

Alternatif bir tekniğe GridView s denetim hiyerarşisini yönetirAn Alternate Technique Manipulates the GridView s Control Hierarchy

Şekil 4: alternatif bir teknik, GridView s denetim hiyerarşisini yönetir (tam boyutlu görüntüyü görüntülemek için tıklatın)Figure 4: An Alternate Technique Manipulates the GridView s Control Hierarchy (Click to view full-size image)

Bu öğreticide, sıralama Kullanıcı deneyimini özelleştirmek için bu son yaklaşımı kullanacağız.For this tutorial, we'll use this latter approach to customize the sorting user experience.

Note

Bu öğreticide kullandığım kod, Teemu Keiski blog girişinde sunulan örneğe dayanır ve GridView sıralama gruplandırmasına sahip bir bit yürütüyordu.The code I m presenting in this tutorial is based on the example provided in Teemu Keiski s blog entry, Playing a Bit with GridView Sort Grouping.

3. Adım: GridView s denetim hiyerarşisine ayırıcı satırları eklemeStep 3: Adding the Separator Rows to the GridView s Control Hierarchy

Yalnızca denetim hiyerarşisi oluşturulduktan ve bu sayfada son kez oluşturulduktan sonra yalnızca GridView s denetim hiyerarşisine ayırıcı satırları eklemek istiyoruz. bu ekleme işlemini sayfa yaşam döngüsünün sonuna, ancak gerçek GridView c 'den önce yapmak istiyoruz oncontrol hiyerarşisi HTML olarak işlendi.Since we only want to add the separator rows to the GridView s control hierarchy after its control hierarchy has been created and created for the last time on that page visit, we want to perform this addition at the end of the page lifecycle, but before the actual GridView control hierarchy has been rendered into HTML. Bunu gerçekleştirebilmemiz mümkün olan en son nokta, aşağıdaki yöntem imzasını kullanarak arka plan kod sınıfında geçersiz kılabildikleri Page sınıf s Render olayıdır:The latest possible point at which we can accomplish this is the Page class s Render event, which we can override in our code-behind class using the following method signature:

protected override void Render(HtmlTextWriter writer)
{
    // Add code to manipulate the GridView control hierarchy
    base.Render(writer);
}

Page sınıf özgün Render yöntemi çağrıldığında base.Render(writer) sayfadaki denetimlerin her biri işlenir ve bu da denetim hiyerarşisine göre biçimlendirme oluşturulur.When the Page class s original Render method is invoked base.Render(writer) each of the controls in the page will be rendered, generating the markup based on their control hierarchy. Bu nedenle, her ikisi de base.Render(writer)çağırdığımızda, sayfanın işlenmesi ve GridView s denetim hiyerarşisini base.Render(writer)çağrılmadan önce işlememiz ve bu sayede, ayırıcı satırların, işlenmeden önce GridView s denetim hiyerarşisine eklenmesi gerekir.Therefore it is imperative that we both call base.Render(writer), so that the page is rendered, and that we manipulate the GridView s control hierarchy prior to calling base.Render(writer), so that the separator rows have been added to the GridView s control hierarchy before it s been rendered.

Sıralama grubu üstbilgilerini eklemek için ilk olarak kullanıcının verilerin sıralanmasını istediğinden emin olmanız gerekir.To inject the sort group headers we first need to ensure that the user has requested that the data be sorted. Varsayılan olarak, GridView s içerikleri sıralanmaz ve bu nedenle herhangi bir grup sıralama üst bilgisi girmemiz gerekmez.By default, the GridView s contents are not sorted, and therefore we don t need to enter any group sorting headers.

Note

GridView 'un sayfa ilk yüklendiğinde belirli bir sütuna göre sıralanmasını istiyorsanız, ilk sayfada GridView s Sort yöntemini çağırın (sonraki geri göndermeler üzerinde değil).If you want the GridView to be sorted by a particular column when the page is first loaded, call the GridView s Sort method on the first page visit (but not on subsequent postbacks). Bunu gerçekleştirmek için, bu çağrıyı bir if (!Page.IsPostBack) koşullu içindeki Page_Load olay işleyicisine ekleyin.To accomplish this, add this call in the Page_Load event handler within an if (!Page.IsPostBack) conditional. Sort yöntemi hakkında daha fazla bilgi için sayfalama ve rapor veri öğreticisi bilgilerini sıralama bölümüne bakın.Refer back to the Paging and Sorting Report Data tutorial information for more on the Sort method.

Verilerin sıralandığı varsayılarak, bir sonraki göreviniz, verilerin hangi sütun tarafından sıralanacağını belirlemektir ve sonra bu sütun s değerlerinde farklılık gösteren satırları tarar.Assuming that the data has been sorted, our next task is to determine what column the data was sorted by and then to scan the rows looking for differences in that column s values. Aşağıdaki kod, verilerin sıralanmasını ve verilerin sıralandığı sütunu bulmasını sağlar:The following code ensures that the data has been sorted and finds the column by which the data has been sorted:

protected override void Render(HtmlTextWriter writer)
{
    // Only add the sorting UI if the GridView is sorted
    if (!string.IsNullOrEmpty(ProductList.SortExpression))
    {
        // Determine the index and HeaderText of the column that
        //the data is sorted by
        int sortColumnIndex = -1;
        string sortColumnHeaderText = string.Empty;
        for (int i = 0; i < ProductList.Columns.Count; i++)
        {
            if (ProductList.Columns[i].SortExpression.CompareTo(ProductList.SortExpression)
                == 0)
            {
                sortColumnIndex = i;
                sortColumnHeaderText = ProductList.Columns[i].HeaderText;
                break;
            }
        }
        // TODO: Scan the rows for differences in the sorted column�s values
}

GridView henüz sıralanmışsa, GridView s SortExpression özelliği ayarlanmayacak.If the GridView has yet to be sorted, the GridView s SortExpression property will not have been set. Bu nedenle, yalnızca bu özellikte bir değer varsa, ayırıcı satırları eklemek istiyoruz.Therefore, we only want to add the separator rows if this property has some value. Bunu yaparsanız, bir sonraki, verilerin sıralandığı sütunun dizinini belirlememiz gerekir.If it does, we next need to determine the index of the column by which the data was sorted. Bu, SortExpression özelliği GridView s SortExpression özelliğine eşit olan sütunu arayarak GridView s Columns koleksiyonu aracılığıyla gerçekleştirilir.This is accomplished by looping through the GridView s Columns collection, searching for the column whose SortExpression property equals the GridView s SortExpression property. Sütun s dizinine ek olarak, ayırıcı satırları görüntülerken kullanılan HeaderText özelliğini de sunuyoruz.In addition to the column s index, we also grab the HeaderText property, which is used when displaying the separator rows.

Verilerin sıralandığı sütunun diziniyle birlikte, son adım GridView 'un satırlarını numaralandırmalıdır.With the index of the column by which the data is sorted, the final step is to enumerate the rows of the GridView. Her satır için, sıralanan sütun s değerinin, önceki satır sıralı sütun değerinden farklı olup olmadığını belirlememiz gerekir.For each row we need to determine whether the sorted column s value differs from the previous row s sorted column s value. Bu durumda, denetim hiyerarşisine yeni bir GridViewRow örneği ekleyebilmemiz gerekir.If so, we need to inject a new GridViewRow instance into the control hierarchy. Bu, aşağıdaki kodla gerçekleştirilir:This is accomplished with the following code:

protected override void Render(HtmlTextWriter writer)
{
    // Only add the sorting UI if the GridView is sorted
    if (!string.IsNullOrEmpty(ProductList.SortExpression))
    {
        // ... Code for finding the sorted column index removed for brevity ...
        // Reference the Table the GridView has been rendered into
        Table gridTable = (Table)ProductList.Controls[0];
        // Enumerate each TableRow, adding a sorting UI header if
        // the sorted value has changed
        string lastValue = string.Empty;
        foreach (GridViewRow gvr in ProductList.Rows)
        {
            string currentValue = gvr.Cells[sortColumnIndex].Text;
            if (lastValue.CompareTo(currentValue) != 0)
            {
                // there's been a change in value in the sorted column
                int rowIndex = gridTable.Rows.GetRowIndex(gvr);
                // Add a new sort header row
                GridViewRow sortRow = new GridViewRow(rowIndex, rowIndex,
                    DataControlRowType.DataRow, DataControlRowState.Normal);
                TableCell sortCell = new TableCell();
                sortCell.ColumnSpan = ProductList.Columns.Count;
                sortCell.Text = string.Format("{0}: {1}",
                    sortColumnHeaderText, currentValue);
                sortCell.CssClass = "SortHeaderRowStyle";
                // Add sortCell to sortRow, and sortRow to gridTable
                sortRow.Cells.Add(sortCell);
                gridTable.Controls.AddAt(rowIndex, sortRow);
                // Update lastValue
                lastValue = currentValue;
            }
        }
    }
    base.Render(writer);
}

Bu kod, GridView s denetim hiyerarşisinin kökünde bulunan Table nesnesine programlı olarak başvurarak ve lastValueadlı bir dize değişkeni oluşturarak başlar.This code starts by programmatically referencing the Table object found at the root of the GridView s control hierarchy and creating a string variable named lastValue. lastValue, sıradaki sütun değerini önceki satır ile karşılaştırmak için kullanılır.lastValue is used to compare the current row s sorted column value with the previous row s value. Ardından, GridView s Rows koleksiyonu numaralandırılır ve her satır için sıralanmış sütunun değeri currentValue değişkeninde depolanır.Next, the GridView s Rows collection is enumerated and for each row the value of the sorted column is stored in the currentValue variable.

Note

Belirli bir satır sıralı sütun değerini öğrenmek için Text özelliğini kullanın.To determine the value of the particular row s sorted column I use the cell s Text property. Bu, BoundFields için iyi çalışır, ancak TemplateFields, CheckBoxFields vb. için istendiği gibi çalışmayacaktır.This works well for BoundFields, but will not work as desired for TemplateFields, CheckBoxFields, and so on. Diğer GridView alanları için kısa süre içinde nasıl hesaba bakacağız.We'll look at how to account for alternate GridView fields shortly.

currentValue ve lastValue değişkenleri karşılaştırılır.The currentValue and lastValue variables are then compared. Farklıysa, denetim hiyerarşisine yeni bir ayırıcı satırı eklememiz gerekir.If they differ we need to add a new separator row to the control hierarchy. Bu, Table nesne s Rows koleksiyonundaki GridViewRow dizininin belirlenmesi, yeni GridViewRow ve TableCell örneklerin oluşturulması ve ardından TableCell ve GridViewRow denetim hiyerarşisine eklenmesi ile gerçekleştirilir.This is accomplished by determining the index of the GridViewRow in the Table object s Rows collection, creating new GridViewRow and TableCell instances, and then adding the TableCell and GridViewRow to the control hierarchy.

TableCell ayırıcı satırı, GridView 'un tüm genişliğini kapsayacak şekilde biçimlendirilir, SortHeaderRowStyle CSS sınıfı kullanılarak biçimlendirilir ve hem sıralama grubu adını (kategori gibi) hem de grup s değerini (alkoller gibi) göstermek için Text özelliğine sahiptir.Note that the separator row s lone TableCell is formatted such that it spans the entire width of the GridView, is formatted using the SortHeaderRowStyle CSS class, and has its Text property such that it shows both the sort group name (such as Category ) and the group s value (such as Beverages ). Son olarak, lastValue currentValuedeğerine güncellenir.Finally, lastValue is updated to the value of currentValue.

Sıralama grubu üst bilgi satırı SortHeaderRowStyle biçimlendirmek için kullanılan CSS sınıfı Styles.css dosyasında belirtilmelidir.The CSS class used to format the sorting group header row SortHeaderRowStyle needs to be specified in the Styles.css file. Size her türlü stil ayarı kullanmayı ücretsiz olarak kullanabilirsiniz; Şunları kullandım:Feel free to use whatever style settings appeal to you; I used the following:

.SortHeaderRowStyle
{
    background-color: #c00;
    text-align: left;
    font-weight: bold;
    color: White;
}

Geçerli kodla sıralama arabirimi, herhangi bir BoundField tarafından sıralandığında sıralama grubu üst bilgilerini ekler (tedarikçiye göre sıralandığında bir ekran görüntüsü gösterir).With the current code, the sorting interface adds sort group headers when sorting by any BoundField (see Figure 5, which shows a screenshot when sorting by supplier). Ancak, diğer herhangi bir alan türüne göre (örneğin, CheckBoxField veya TemplateField) sıralama yaparken, sıralama grubu üst bilgileri nerede bulunur (bkz. Şekil 6).However, when sorting by any other field type (such as a CheckBoxField or TemplateField), the sort group headers are nowhere to be found (see Figure 6).

Sıralama arabirimine , BoundFields 'e göre sıralarken sıralama grubu üst bilgilerini IçerirThe Sorting Interface Includes Sort Group Headers When Sorting by BoundFields

Şekil 5: sıralama arabirimi, boundfields 'e göre sıralarken sıralama grubu üstbilgilerini içerir (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 5: The Sorting Interface Includes Sort Group Headers When Sorting by BoundFields (Click to view full-size image)

CheckBoxField sıralanırken sıralama grubu üst bilgileri eksik The Sort Group Headers are Missing When Sorting a CheckBoxField

Şekil 6: bir CheckBoxField sıralanırken sıralama grubu başlıkları eksik (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 6: The Sort Group Headers are Missing When Sorting a CheckBoxField (Click to view full-size image)

Bir CheckBoxField tarafından sıralandığında sıralama grubu üst bilgilerinin eksik olmasının nedeni, kodun Şu anda her satır için sıralanmış sütunun değerini belirlemede yalnızca TableCell s Text özelliğini kullanmalardır.The reason the sort group headers are missing when sorting by a CheckBoxField is because the code currently uses just the TableCell s Text property to determine the value of the sorted column for each row. CheckBoxFields için TableCell s Text özelliği boş bir dizedir; Bunun yerine, değer TableCell s Controls koleksiyonu içinde bulunan bir CheckBox Web denetimi aracılığıyla kullanılabilir.For CheckBoxFields, the TableCell s Text property is an empty string; instead, the value is available through a CheckBox Web control that resides within the TableCell s Controls collection.

BoundFields dışındaki alan türlerini işlemek için, TableCell s Controls koleksiyonundaki onay kutusunun varlığını denetlemek üzere currentValue değişkeninin atandığı kodu geliştirmemiz gerekir.To handle field types other than BoundFields, we need to augment the code where the currentValue variable is assigned to check for the existence of a CheckBox in the TableCell s Controls collection. currentValue = gvr.Cells[sortColumnIndex].Textkullanmak yerine, bu kodu aşağıdaki kodla değiştirin:Instead of using currentValue = gvr.Cells[sortColumnIndex].Text, replace this code with the following:

string currentValue = string.Empty;
if (gvr.Cells[sortColumnIndex].Controls.Count > 0)
{
    if (gvr.Cells[sortColumnIndex].Controls[0] is CheckBox)
    {
        if (((CheckBox)gvr.Cells[sortColumnIndex].Controls[0]).Checked)
            currentValue = "Yes";
        else
            currentValue = "No";
    }
    // ... Add other checks here if using columns with other
    //      Web controls in them (Calendars, DropDownLists, etc.) ...
}
else
    currentValue = gvr.Cells[sortColumnIndex].Text;

Bu kod, Controls koleksiyonunda herhangi bir denetim olup olmadığını anlamak için geçerli satır için TableCell sıralanmış sütunu inceler.This code examines the sorted column TableCell for the current row to determine if there are any controls in the Controls collection. Varsa ve ilk denetim bir onay kutusu ise, CheckBox s Checked özelliğine bağlı olarak currentValue değişkeni Evet veya Hayır olarak ayarlanır.If there are, and the first control is a CheckBox, the currentValue variable is set to Yes or No, depending on the CheckBox s Checked property. Aksi takdirde, değer TableCell s Text özelliğinden alınır.Otherwise, the value is taken from the TableCell s Text property. Bu mantık, GridView 'da mevcut olabilecek herhangi bir TemplateFields için sıralamayı işlemek üzere çoğaltılabilir.This logic can be replicated to handle sorting for any TemplateFields that may exist in the GridView.

Yukarıdaki kod ek olarak, sıralama grubu üstbilgileri artık Discontinued CheckBoxField tarafından sıralandığında mevcuttur (bkz. Şekil 7).With the above code addition, the sort group headers are now present when sorting by the Discontinued CheckBoxField (see Figure 7).

, bir CheckBoxField sıralanırken artık sıralama grubu üst bilgileri mevcutturThe Sort Group Headers are Now Present When Sorting a CheckBoxField

Şekil 7: bir CheckBoxField sıralaması yaparken sıralama grubu üstbilgileri artık mevcuttur (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 7: The Sort Group Headers are Now Present When Sorting a CheckBoxField (Click to view full-size image)

Note

CategoryID, SupplierIDveya UnitPrice alanları için NULL veritabanı değerlerine sahip ürünleriniz varsa, bu değerler GridView 'da varsayılan olarak boş dizeler olarak görünür, yani bu ürünler için, NULL değerleri olan bu ürünlerin ayırıcı satır s metni kategori gibi okuyacaktır: (yani, kategoriden sonra hiçbir ad yok: iş kolları gibi).If you have products with NULL database values for the CategoryID, SupplierID, or UnitPrice fields, those values will appear as empty strings in the GridView by default, meaning the separator row s text for those products with NULL values will read like Category: (that is, there s no name after Category: like with Category: Beverages ). Burada bir değer görüntülenmesini istiyorsanız, BoundFields NullDisplayText özelliğini görüntülenmesini istediğiniz metin olarak ayarlayabilir ya da currentValue ayırıcı satır s Text özelliğine atarken Render yöntemine bir koşullu ifade ekleyebilirsiniz.If you want a value displayed here you can either set the BoundFields NullDisplayText property to the text you want displayed or you can add a conditional statement in the Render method when assigning the currentValue to the separator row s Text property.

ÖzetSummary

GridView sıralama arabirimini özelleştirmek için birçok yerleşik seçenek içermez.The GridView does not include many built-in options for customizing the sorting interface. Ancak, düşük düzeyde bir kod ile, daha özelleştirilmiş bir arabirim oluşturmak için GridView s denetim hiyerarşisi ince ayar mümkündür.However, with a bit of low-level code, it s possible to tweak the GridView s control hierarchy to create a more customized interface. Bu öğreticide, farklı grupları ve bu grup sınırlarını daha kolay bir şekilde tanımlayan, sıralanabilir bir GridView için sıralama grubu ayırıcı satırı eklemeyi gördük.In this tutorial we saw how to add a sort group separator row for a sortable GridView, which more easily identifies the distinct groups and those groups boundaries. Özelleştirilmiş sıralama arabirimleri hakkında daha fazla örnek için, Scott Guthrie s ' nin birkaç ASP.NET 2,0 GridView sıralama ipucu ve püf günlüğü girişini inceleyin.For additional examples of customized sorting interfaces, check out Scott Guthrie s A Few ASP.NET 2.0 GridView Sorting Tips and Tricks blog entry.

Programlamanın kutlu olsun!Happy Programming!

Yazar hakkındaAbout the Author

4GuysFromRolla.com 'in, Scott Mitchell, yedi ASP/ASP. net books ve 'in yazarı, 1998 sürümünden bu yana Microsoft Web teknolojileriyle çalışmaktadır.Scott Mitchell, author of seven ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Scott bağımsız danışman, Trainer ve yazıcı olarak çalışıyor.Scott works as an independent consultant, trainer, and writer. En son kitabı, 24 saat içinde ASP.NET 2,0 kendi kendinize eğitimister.His latest book is Sams Teach Yourself ASP.NET 2.0 in 24 Hours. mitchell@4GuysFromRolla.comadresinden erişilebilir .He can be reached at mitchell@4GuysFromRolla.com. ya da blog aracılığıyla http://ScottOnWriting.NETbulabilirsiniz.or via his blog, which can be found at http://ScottOnWriting.NET.