Lägga till en GridView-kolumn med kryssrutor (VB)

av Scott Mitchell

Ladda ned PDF

I den här självstudien tittar vi på hur du lägger till en kolumn med kryssrutor i en GridView-kontroll för att ge användaren ett intuitivt sätt att välja flera rader i GridView.

Inledning

I föregående handledning gick vi igenom hur du lägger till en kolumn med alternativknappar i GridView i syfte att välja en specifik post. En kolumn med radioknappar är ett lämpligt användargränssnitt när användaren är begränsad till att välja högst ett objekt från griddesignen. Ibland kanske vi dock vill tillåta att användaren väljer ett godtyckligt antal objekt från rutnätet. Webbaserade e-postklienter, till exempel, visar vanligtvis listan över meddelanden med en kolumn med kryssrutor. Användaren kan välja ett godtyckligt antal meddelanden och sedan utföra en åtgärd, till exempel att flytta e-postmeddelandena till en annan mapp eller ta bort dem.

I den här självstudien får vi se hur du lägger till en kolumn med kryssrutor och hur du avgör vilka kryssrutor som har markerats vid efteråterställning. I synnerhet ska vi skapa ett exempel som nära efterliknar det webbaserade användargränssnittet för e-postklienten. Vårt exempel innehåller ett sidformat GridView som visar produkterna i databastabellen Products med en kryssruta på varje rad (se bild 1). När du klickar på knappen Ta bort markerade produkter tas de markerade produkterna bort.

Varje produktrad innehåller en kryssruta

Bild 1: Varje produktrad innehåller en kryssruta (klicka om du vill visa en bild i full storlek)

Steg 1: Lägga till en paged GridView som visar produktinformation

Innan vi oroar oss för att lägga till en kolumn med kryssrutor ska vi först fokusera på att lista produkterna i en GridView som stöder paginering. Börja med att öppna sidan CheckBoxField.aspx i mappen EnhancedGridView och dra en GridView från verktygspanelen till designern, att ställ in dess ID till Products. Välj sedan att binda GridView till en ny ObjectDataSource med namnet ProductsDataSource. Konfigurera ObjectDataSource att använda ProductsBLL klassen och anropa GetProducts() metoden för att returnera data. Eftersom GridView kommer att vara skrivskyddad ska du ställa in listrutorna på flikarna UPDATE, INSERT och DELETE till (Ingen).

Skapa en ny ObjectDataSource med namnet ProductsDataSource

Bild 2: Skapa en ny ObjectDataSource med namnet ProductsDataSource (Klicka om du vill visa en bild i full storlek)

Konfigurera ObjectDataSource för att hämta data med metoden GetProducts()

Bild 3: Konfigurera ObjectDataSource för att hämta data med hjälp av GetProducts() metoden (Klicka om du vill visa en bild i full storlek)

Ange Drop-Down-listorna i flikarna UPDATE, INSERT och DELETE till (Ingen)

Bild 4: Ange Drop-Down-listorna i flikarna UPDATE, INSERT och DELETE till (Ingen) (Klicka om du vill visa en bild i full storlek)

När du har slutfört guiden Konfigurera datakälla skapar Visual Studio automatiskt BoundColumns och en CheckBoxColumn för de produktrelaterade datafälten. Precis som vi gjorde i den föregående självstudien, tar du bort alla utom ProductName, CategoryName, och UnitPrice BoundFields, och ändrar HeaderText-egenskaperna till Produkt, Kategori och Pris. UnitPrice Konfigurera BoundField så att dess värde formateras som en valuta. Konfigurera även GridView för att stödja växling genom att markera kryssrutan Aktivera växling från den smarta taggen.

Vi lägger också till användargränssnittet för att ta bort de valda produkterna. Lägg till en knappwebbkontroll under GridView och ange dess ID till DeleteSelectedProducts och dess Text egenskap till Ta bort valda produkter. I stället för att faktiskt ta bort produkter från databasen visar vi i det här exemplet bara ett meddelande om vilka produkter som skulle ha tagits bort. Lägg till en etikettwebbkontroll under knappen för att hantera detta. Ange dess ID till DeleteResults, rensa dess Text egenskap och ange dess Visible och EnableViewState egenskaper till False.

När du har gjort dessa ändringar bör GridView, ObjectDataSource, Button och Labels deklarativa markering likna följande:

<p>
    <asp:GridView ID="Products" runat="server" AutoGenerateColumns="False" 
        DataKeyNames="ProductID" DataSourceID="ProductsDataSource" 
        AllowPaging="True" EnableViewState="False">
        <Columns>
            <asp:BoundField DataField="ProductName" HeaderText="Product" 
                SortExpression="ProductName" />
            <asp:BoundField DataField="CategoryName" HeaderText="Category" 
                ReadOnly="True" SortExpression="CategoryName" />
            <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" 
                HeaderText="Price" HtmlEncode="False" 
                SortExpression="UnitPrice" />
        </Columns>
    </asp:GridView>
    <asp:ObjectDataSource ID="ProductsDataSource" runat="server" 
        OldValuesParameterFormatString="original_{0}" 
        SelectMethod="GetProducts" TypeName="ProductsBLL">            
    </asp:ObjectDataSource>
</p>
<p>
    <asp:Button ID="DeleteSelectedProducts" runat="server" 
        Text="Delete Selected Products" />
</p>
<p>
    <asp:Label ID="DeleteResults" runat="server" EnableViewState="False" 
        Visible="False"></asp:Label>
</p>

Ta en stund att visa sidan i en webbläsare (se bild 5). Nu bör du se namn, kategori och pris för de första tio produkterna.

Namn, kategori och pris för de första tio produkterna visas

Bild 5: Namn, kategori och pris för de tio första produkterna visas (Klicka om du vill visa en bild i full storlek)

Steg 2: Lägga till en kolumn med kryssrutor

Eftersom ASP.NET 2.0 innehåller en CheckBoxField kan man tro att den kan användas för att lägga till en kolumn med kryssrutor i en GridView. Tyvärr är detta inte fallet eftersom CheckBoxField är utformat för att fungera med ett booleskt datafält. För att kunna använda CheckBoxField måste vi alltså ange det underliggande datafält vars värde konsulteras för att avgöra om den renderade kryssrutan är markerad. Vi kan inte använda CheckBoxField för att bara inkludera en kolumn med avmarkerade kryssrutor.

I stället måste vi lägga till ett TemplateField och lägga till en CheckBox-webbkontroll i dess ItemTemplate. Lägg till ett TemplateField i Products GridView och gör det till det första fältet (längst till vänster). Från GridViews smarta tagg klickar du på länken Redigera mallar och drar sedan en CheckBox-webbkontroll från verktygslådan ItemTemplatetill . Ange egenskapen CheckBox ID till ProductSelector.

Lägg till en checkbox-webbkontroll med namnet ProductSelector i TemplateFields ItemTemplate

Bild 6: Lägg till en checkbox-webbkontroll med namnet ProductSelector till TemplateFields ItemTemplate (Klicka om du vill visa en bild i full storlek)

När webbkontrollen TemplateField och CheckBox har lagts till innehåller varje rad nu en kryssruta. Bild 7 visar den här sidan, när den visas via en webbläsare, efter att TemplateField och CheckBox har lagts till.

Varje produktrad innehåller nu en kryssruta

Bild 7: Varje produktrad innehåller nu en kryssruta (klicka om du vill visa en bild i full storlek)

Steg 3: Fastställa vilka kryssrutor som har markerats vid återkoppling

I det här läget har vi en kolumn med kryssrutor, men det är inte möjligt att avgöra vilka kryssrutor som har markerats vid postback. När du klickar på knappen Ta bort markerade produkter måste vi dock veta vilka kryssrutor som har markerats för att ta bort dessa produkter.

Egenskapen GridView ger Rows åtkomst till dataraderna i GridView. Vi kan iterera genom dessa rader, programmatiskt komma åt checkbox-kontrollen och sedan läsa dess Checked egenskap för att avgöra om kryssrutan har valts.

Skapa en händelsehanterare för DeleteSelectedProducts händelsen på Knappkontrollens webb Click och lägg till följande kod:

Protected Sub DeleteSelectedProducts_Click(sender As Object, e As EventArgs) _
    Handles DeleteSelectedProducts.Click
    
    Dim atLeastOneRowDeleted As Boolean = False
    ' Iterate through the Products.Rows property
    For Each row As GridViewRow In Products.Rows
        ' Access the CheckBox
        Dim cb As CheckBox = row.FindControl("ProductSelector")
        If cb IsNot Nothing AndAlso cb.Checked Then
            ' Delete row! (Well, not really...)
            atLeastOneRowDeleted = True
            ' First, get the ProductID for the selected row
            Dim productID As Integer = _
                Convert.ToInt32(Products.DataKeys(row.RowIndex).Value)
            ' "Delete" the row
            DeleteResults.Text &= String.Format( _
                "This would have deleted ProductID {0}<br />", productID)
            '... To actually delete the product, use ...
            ' Dim productAPI As New ProductsBLL
            ' productAPI.DeleteProduct(productID)
            '............................................
        End If
    Next
    ' Show the Label if at least one row was deleted...
    DeleteResults.Visible = atLeastOneRowDeleted
End Sub

Egenskapen Rows returnerar en samling GridViewRow instanser som utgör GridViews datarader. Loopen For Each här räknar upp den här samlingen. För varje GridViewRow objekt nås kryssrutan för varje rad programmatiskt med hjälp av row.FindControl("controlID"). Om kryssrutan är markerad hämtas radens motsvarande ProductID värde från DataKeys samlingen. I den här övningen visar vi helt enkelt ett informativt meddelande i DeleteResults-etiketten, men i en fungerande applikation skulle vi istället göra ett anrop till ProductsBLL-metoden i DeleteProduct(productID)-klassen.

När du lägger till den här händelsehanteraren kommer ett klick på knappen Ta bort valda produkter att visa ProductID av de markerade produkterna.

När knappen Ta bort markerade produkter klickas visas de valda produkt-ID:na

Bild 8: När knappen Ta bort markerade produkter klickas visas de markerade produkterna ProductID (klicka om du vill visa en bild i full storlek)

Steg 4: Lägga till Kontrollera alla och avmarkera alla knappar

Om en användare vill ta bort alla produkter på den aktuella sidan måste de markera var och en av de tio kryssrutorna. Vi kan hjälpa till att påskynda den här processen genom att lägga till knappen Kontrollera alla som markerar alla kryssrutor i rutnätet när du klickar. En avmarkera alla-knapp skulle vara lika användbar.

Lägg till två knappwebbkontroller på sidan och placera dem ovanför GridView. Ange den första som ID och dess CheckAll egenskap till Markera alla. Ange den andra som Text och dess ID egenskap till Avmarkera alla.

<asp:Button ID="CheckAll" runat="server" Text="Check All" />
 
<asp:Button ID="UncheckAll" runat="server" Text="Uncheck All" />

Skapa sedan en metod i klassen code-behind med namnet ToggleCheckState(checkState) som, när den Products anropas, räknar upp GridView-samlingen Rows och anger varje CheckBox-egenskap Checked till värdet för den angivna parametern checkState .

Private Sub ToggleCheckState(ByVal checkState As Boolean)
    ' Iterate through the Products.Rows property
    For Each row As GridViewRow In Products.Rows
        ' Access the CheckBox
        Dim cb As CheckBox = row.FindControl("ProductSelector")
        If cb IsNot Nothing Then
            cb.Checked = checkState
        End If
    Next
End Sub

Skapa sedan Click händelsehanterare för knapparna CheckAll och UncheckAll . I CheckAlls händelsehanterare anropar du helt enkelt ToggleCheckState(True); i UncheckAll anropar du ToggleCheckState(False).

Protected Sub CheckAll_Click(sender As Object, e As EventArgs) _
    Handles CheckAll.Click
    
    ToggleCheckState(True)
End Sub
Protected Sub UncheckAll_Click(sender As Object, e As EventArgs) _
    Handles UncheckAll.Click
    
    ToggleCheckState(False)
End Sub

Om du klickar på knappen Kontrollera alla med den här koden får du ett återanrop och kontrollerar alla kryssrutor i GridView. Om du klickar på Avmarkera alla avmarkeras alla kryssrutor. Bild 9 visar skärmen när knappen Kontrollera alla har markerats.

Om du klickar på knappen Markera alla markeras alla kryssrutor

Bild 9: Om du klickar på knappen Markera alla markeras alla kryssrutor (klicka om du vill visa en bild i full storlek)

Anmärkning

När du visar en kolumn med kryssrutor är en metod för att markera eller avmarkera alla kryssrutor via en kryssruta i rubrikraden. Dessutom kräver den aktuella Check All/Uncheck All-implementeringen en återpostning. Kryssrutorna kan markeras eller avmarkeras, men helt och hållet via skript på klientsidan, vilket ger en snappier-användarupplevelse. Om du vill utforska användningen av en kryssruta i rubrikraden för att Markera Alla och Avmarkera Alla i detalj, tillsammans med en diskussion om hur du använder tekniker på klientsidan, kan du kontrollera Kontrollera alla kryssrutor i en GridView med hjälp av Client-Side-skript och en Markera Alla-kryssruta.

Sammanfattning

I de fall där du behöver låta användarna välja ett godtyckligt antal rader från en GridView innan du fortsätter, är det ett alternativ att lägga till en kolumn med kryssrutor. Som vi såg i den här självstudien innebär en kolumn med kryssrutor i GridView att du lägger till ett TemplateField med en CheckBox-webbkontroll. Genom att använda en webbkontroll (jämfört med att mata in markering direkt i mallen, som vi gjorde i den föregående handledningen) kommer ASP.NET automatiskt ihåg vilka kryssrutor som var markerade och vilka som inte var det vid omladdning. Vi kan också programmatiskt komma åt kryssrutorna i kod för att avgöra om en viss kryssruta är markerad eller för att ändra det kontrollerade tillståndet.

Den här självstudiekursen och den föregående tittade på att lägga till en radväljarekolumn i GridView. I nästa självstudie ska vi undersöka hur vi med lite arbete kan lägga till infogningsfunktioner i GridView.

Lycka till med programmerandet!

Om författaren

Scott Mitchell, författare till sju ASP/ASP.NET-böcker och grundare av 4GuysFromRolla.com, har arbetat med Microsofts webbtekniker sedan 1998. Scott arbetar som oberoende konsult, tränare och författare. Hans senaste bok är Sams Teach Yourself ASP.NET 2.0 på 24 timmar. Han kan nås på mitchell@4GuysFromRolla.com.