Dela via


Anpassa gränssnittet för datamodifiering (VB)

av Scott Mitchell

Ladda ned PDF

I den här självstudien ska vi titta på hur du anpassar gränssnittet för en redigerbar GridView genom att ersätta standardkontrollerna TextBox och CheckBox med alternativa webbkontroller för indata.

Inledning

Kontrollerna BoundFields och CheckBoxFields som används av kontrollerna GridView och DetailsView förenklar processen för att ändra data på grund av deras möjlighet att återge skrivskyddade, redigerbara och infogbara gränssnitt. Dessa gränssnitt kan återges utan att du behöver lägga till ytterligare deklarativ kod. BoundField- och CheckBoxField-gränssnitten saknar dock den anpassningsbarhet som ofta behövs i verkliga scenarier. För att kunna anpassa det redigerbara eller infogbara gränssnittet i ett GridView- eller DetailsView-gränssnitt måste vi i stället använda ett TemplateField.

I föregående självstudie såg vi hur du anpassar gränssnitten för datamodifiering genom att lägga till verifieringswebbkontroller. I den här självstudien ska vi titta på hur du anpassar de faktiska webbkontrollerna för datainsamling och ersätter boundfield- och CheckBoxField-standardkontrollerna TextBox och CheckBox med alternativa webbkontroller för indata. I synnerhet skapar vi en redigerbar GridView som gör att en produkts namn, kategori, leverantör och utgångna status kan uppdateras. När du redigerar en viss rad återges kategori- och leverantörsfälten som listrutor, som innehåller den uppsättning tillgängliga kategorier och leverantörer som du kan välja mellan. Dessutom ersätter vi CheckBoxFields standardkontroll med en RadioButtonList-kontroll som erbjuder två alternativ: "Active" och "Discontinued".

GridViewens redigeringsgränssnitt inkluderar listrutor och radioknappar

Bild 1: GridViews redigeringsgränssnitt innehåller listrutor och radioknappar (klicka om du vill visa en bild i full storlek)

Steg 1: Att skapa lämpligUpdateProductöverbelastning

I den här självstudien skapar vi en redigerbar GridView som tillåter redigering av en produkts namn, kategori, leverantör och utgångna status. Därför behöver vi en UpdateProduct överbelastning som accepterar fem indataparametrar: dessa fyra produktvärden plus ProductID. Precis som i våra tidigare överlaster kommer den här att:

  1. Hämta produktinformationen från databasen för den angivna ProductID,
  2. Uppdatera fälten ProductName, CategoryID, SupplierIDoch Discontinued och
  3. Skicka uppdateringsbegäran Update() till DAL via TableAdapter-metoden.

För korthetens skull har jag för den här specifika överbelastningen utelämnat kontrollen av affärsregel som säkerställer att en produkt som markeras som utgången inte är den enda produkten som leverantören erbjuder. Lägg gärna till den i om du vill, eller helst omstrukturera logiken till en separat metod.

Följande kod visar den nya överbelastningen UpdateProduct i klassen ProductsBLL:

<System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, False)>
Public Function UpdateProduct(
    ByVal productName As String, ByVal categoryID As Nullable(Of Integer), 
    ByVal supplierID As Nullable(Of Integer), ByVal discontinued As Boolean, 
    ByVal productID As Integer)
    As Boolean
    Dim products As Northwind.ProductsDataTable = Adapter.GetProductByProductID(productID)
    If products.Count = 0 Then
        Return False
    End If
    Dim product As Northwind.ProductsRow = products(0)
    product.ProductName = productName
    If Not supplierID.HasValue Then
        product.SetSupplierIDNull()
    Else
        product.SupplierID = supplierID.Value
    End If
    If Not categoryID.HasValue Then
        product.SetCategoryIDNull()
    Else
        product.CategoryID = categoryID.Value
    End If
    product.Discontinued = discontinued
    Dim rowsAffected As Integer = Adapter.Update(product)
    Return rowsAffected = 1
End Function

Steg 2: Skapa redigerbara GridView

När överlagringen UpdateProduct har lagts till, är vi redo att påbörja skapandet av vår redigerbara GridView. Öppna sidan CustomizedUI.aspx i EditInsertDelete mappen och lägg till en GridView-kontroll i designern. Skapa sedan en ny ObjectDataSource från GridViews smarta tagg. Konfigurera ObjectDataSource för att hämta produktinformation via ProductBLL klassens GetProducts() -metod och uppdatera produktdata med den UpdateProduct överlagring som vi nyss skapade. På flikarna INSERT och DELETE väljer du (Ingen) i listrutorna.

Konfigurera ObjectDataSource för att använda den UpdateProduct-överlagring som just skapats

Bild 2: Konfigurera ObjectDataSource att använda den UpdateProduct överlagring som just har skapats (klicka om du vill visa en bild i full storlek)

Som vi har sett i självstudierna för dataändring, tilldelar den deklarativa syntaxen för ObjectDataSource, som har skapats av Visual Studio, egenskapen OldValuesParameterFormatString till original_{0}. Detta fungerar naturligtvis inte med vårt affärslogiklager eftersom våra metoder inte förväntar sig att det ursprungliga ProductID värdet ska skickas in. Därför kan du, som vi har gjort i tidigare självstudier, ta en stund att ta bort den här egenskapstilldelningen från den deklarativa syntaxen eller i stället ange egenskapens värde till {0}.

Efter den här ändringen bör ObjectDataSources deklarativa markering se ut så här:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL"
    UpdateMethod="UpdateProduct">
    <UpdateParameters>
        <asp:Parameter Name="productName" Type="String" />
        <asp:Parameter Name="categoryID" Type="Int32" />
        <asp:Parameter Name="supplierID" Type="Int32" />
        <asp:Parameter Name="discontinued" Type="Boolean" />
        <asp:Parameter Name="productID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Observera att egenskapen OldValuesParameterFormatString har tagits bort och att det finns en Parameter i UpdateParameters-samlingen för varje av de indataparametrar som förväntas av vår UpdateProduct-överlagring.

Medan ObjectDataSource är konfigurerat för att endast uppdatera en delmängd av produktvärden, visar GridView för närvarande alla produktfält. Ta en stund att redigera GridView så att:

  • Den innehåller bara ProductName, SupplierName, CategoryName BoundFields och Discontinued CheckBoxField
  • Fälten CategoryName och SupplierName som ska visas före (till vänster om) Discontinued CheckBoxField
  • Egenskapen CategoryName och SupplierName BoundFields HeaderText är inställd på "Kategori" respektive "Leverantör"
  • Redigeringsstöd är aktiverat (markera kryssrutan Aktivera redigering i GridViews smarta tagg)

Efter dessa ändringar ser designern ut ungefär som bild 3, med GridViews deklarativa syntax som visas nedan.

Ta bort de onödiga fälten från GridView

Bild 3: Ta bort de onödiga fälten från GridView (Klicka om du vill visa en bild i full storlek)

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
    <Columns>
        <asp:BoundField DataField="ProductName"
           HeaderText="ProductName" SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category"
           ReadOnly="True"
           SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName" HeaderText="Supplier"
           ReadOnly="True"
           SortExpression="SupplierName" />
        <asp:CheckBoxField DataField="Discontinued"
           HeaderText="Discontinued" SortExpression="Discontinued" />
    </Columns>
</asp:GridView>

Nu är GridViews skrivskyddade beteende slutfört. När du visar data återges varje produkt som en rad i GridView, som visar produktens namn, kategori, leverantör och utgångna status.

GridViews Read-Only-gränssnitt är slutfört

Bild 4: GridViews Read-Only-gränssnitt är slutfört (klicka om du vill visa en bild i full storlek)

Anmärkning

Som diskuterats i en översikt av Infoga, Uppdatera och Ta bort data-tutorial är det mycket viktigt att GridView-vyns tillstånd är aktiverat (standardbeteendet). Om du anger egenskapen GridView EnableViewState till falseriskerar du att samtidiga användare oavsiktligt tar bort eller redigerar poster.

Steg 3: Använda en listruta för gränssnitten för kategori- och leverantörsredigering

Kom ihåg att ProductsRow objektet innehåller CategoryIDegenskaperna , CategoryName, SupplierIDoch SupplierName som anger de faktiska ID-värdena för sekundärnyckeln i databastabellen Products och motsvarande Name värden i tabellerna Categories och Suppliers . ProductRow och CategoryID kan både läsas från och skrivas till, medan egenskaperna SupplierID och CategoryName är markerade som skrivskyddade.

På grund av den skrivskyddade statusen för egenskaperna CategoryName och SupplierName har motsvarande BoundFields fått sin ReadOnly-egenskap inställd på True, vilket förhindrar att dessa värden ändras när en rad redigeras. Även om vi kan ange ReadOnly-egenskapen till False och återge CategoryName och SupplierName som textrutor vid redigering, kommer en sådan metod att resultera i ett undantag när användaren försöker uppdatera produkten, eftersom det inte finns någon UpdateProduct-överlagring som accepterar CategoryName och SupplierName som indata. Faktum är att vi inte vill skapa en sådan överbelastning av två skäl:

  • Tabellen Products saknar SupplierName och CategoryName fält, men har SupplierID och CategoryID. Därför vill vi att vår metod ska skickas dessa specifika ID-värden, inte deras uppslagstabellvärden.
  • Att kräva att användaren skriver in namnet på leverantören eller kategorin är mindre än idealiskt, eftersom det kräver att användaren känner till tillgängliga kategorier och leverantörer och rätt stavning.

Fälten leverantör och kategori bör visa kategorins och leverantörernas namn när de är i skrivskyddat läge (som nu) och en listruta med tillämpliga alternativ när de redigeras. Med hjälp av en listruta kan slutanvändaren snabbt se vilka kategorier och leverantörer som är tillgängliga att välja bland och enklare kan göra sitt val.

För att tillhandahålla det här beteendet behöver vi konvertera SupplierName och CategoryName BoundFields till TemplateFields, där ItemTemplate genererar SupplierName och CategoryName värdena och där EditItemTemplate använder en listrutekontroll för att lista tillgängliga kategorier och leverantörer.

Lägga tillCategoriesochSuppliersDropDownLists

Börja med att konvertera SupplierName och CategoryName BoundFields till TemplateFields genom att klicka på länken "Redigera kolumner" från GridViews smarta tagg, välja BoundField från listan nere till vänster och klicka på länken "Konvertera det här fältet till ett Mallfält". Konverteringsprocessen skapar ett TemplateField med både en ItemTemplate och en EditItemTemplate, enligt deklarativ syntax nedan:

<asp:TemplateField HeaderText="Category" SortExpression="CategoryName">
    <EditItemTemplate>
        <asp:Label ID="Label1" runat="server"
          Text='<%# Eval("CategoryName") %>'></asp:Label>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label1" runat="server"
          Text='<%# Bind("CategoryName") %>'></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

Eftersom BoundField har markerats som skrivskyddad innehåller både ItemTemplate och EditItemTemplate en etikettwebbkontroll vars Text egenskap är bunden till det tillämpliga datafältet (CategoryNamei syntaxen ovan). Vi måste ändra EditItemTemplate och ersätta Label-webbkontrollen med en DropDownList-kontroll.

Som vi har sett i tidigare självstudier kan mallen redigeras via designern eller direkt från deklarativ syntax. Om du vill redigera den via designern klickar du på länken Redigera mallar från GridViews smarta tagg och väljer att arbeta med fältet Kategori.EditItemTemplate Ta bort etikettkontrollen och ersätt den med en DropDownList-kontroll. Ange ID-egenskapen för DropDownList-kontrollen till Categories.

Ta bort TextBox och lägg till en dropdown-lista i EditItemTemplate

Bild 5: Ta bort TexBox och lägg till en listruta i EditItemTemplate (Klicka om du vill visa en bild i full storlek)

Vi måste sedan fylla listrutan med de tillgängliga kategorierna. Klicka på länken Välj datakälla från listrutans smarta tagg och välj att skapa en ny ObjectDataSource med namnet CategoriesDataSource.

Skapa en ny ObjectDataSource-kontroll med namnet CategoriesDataSource

Bild 6: Skapa en ny ObjectDataSource-kontroll med namnet CategoriesDataSource (Klicka om du vill visa en bild i full storlek)

Om du vill att ObjectDataSource ska returnera alla kategorier binder du den till CategoriesBLL klassens GetCategories() -metod.

Bind ObjectDataSource med metoden GetCategories som tillhör CategoriesBLL

Bild 7: Binda ObjectDataSource till CategoriesBLLmetoden 's GetCategories() (Klicka om du vill visa en bild i full storlek)

Konfigurera slutligen listrutans inställningar så att fältet CategoryName visas i varje listruta ListItem med fältet CategoryID som används som värde.

Visa fältet CategoryName och använd CategoryID som värde

Bild 8: Visa fältet CategoryName och CategoryID Använd som värde (Klicka om du vill visa en bild i full storlek)

När du har gjort dessa ändringar kommer den deklarativa koden för EditItemTemplate i CategoryName TemplateField att innehålla både en rullgardinsmeny och en ObjectDataSource.

<asp:TemplateField HeaderText="Category" SortExpression="CategoryName">
    <EditItemTemplate>
        <asp:DropDownList ID="Categories" runat="server"
          DataSourceID="CategoriesDataSource"
          DataTextField="CategoryName" DataValueField="CategoryID">
        </asp:DropDownList>
        <asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
            OldValuesParameterFormatString="original_{0}"
            SelectMethod="GetCategories" TypeName="CategoriesBLL">
        </asp:ObjectDataSource>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label1" runat="server"
          Text='<%# Bind("CategoryName") %>'></asp:Label>
    </ItemTemplate>
</asp:TemplateField>

Anmärkning

Listrutan i EditItemTemplate måste ha dess visningstillstånd aktiverat. Vi kommer snart att lägga till databindningssyntax i DropDownLists deklarativa syntax och databindningskommandon som Eval() och Bind() kan bara visas i kontroller vars visningstillstånd är aktiverat.

Upprepa de här stegen för att lägga till en listruta med namnet Suppliers i SupplierName TemplateFields EditItemTemplate. Detta innebär att lägga till en dropdown-meny i EditItemTemplate och skapa en annan ObjectDataSource. Listrutans Suppliers ObjectDataSource bör däremot konfigureras för att anropa metoden SuppliersBLL i GetSuppliers()-klassen. Dessutom konfigurerar du Suppliers Listrutan så att CompanyName fältet visas och använder SupplierID fältet som värde för dess ListItem.

När du har lagt till DropDownLists till de två EditItemTemplate, läser du in sidan i en webbläsare och klickar på Redigera-knappen för produkten Cajun Seasoning från Chef Anton. Som bild 9 visar återges produktens kategori- och leverantörskolumner som listrutor som innehåller tillgängliga kategorier och leverantörer att välja mellan. Observera dock att de första objekten i båda listrutorna väljs som standard (Drycker för kategorin och Exotic Liquids som leverantör), även om Chef Anton's Cajun Seasoning är en condiment som tillhandahålls av New Orleans Cajun Delights.

Det första objektet i Drop-Down-listorna är markerat som standard

Bild 9: Det första objektet i Drop-Down-listorna är markerat som standard (Klicka om du vill visa en bild i full storlek)

Om du klickar på Uppdatera ser du dessutom att produktens CategoryID och SupplierID värdena är inställda på NULL. Båda dessa oönskade beteenden orsakas eftersom DropDown-listorna i EditItemTemplate-elementen inte är bundna till några datafält från underliggande produktdata.

Binda rullgardinsmenyerna och datafälten tillCategoryIDochSupplierID

För att få den redigerade produktens kategori- och leverantörslistlistor inställda på lämpliga värden och för att dessa värden ska skickas UpdateProduct tillbaka till BLL-metoden när vi klickar på Uppdatera, måste vi binda listrutornas SelectedValue egenskaper till datafälten CategoryID och SupplierID med hjälp av dubbelriktad databindning. Om du vill göra detta med Categories Listrutan kan du lägga till SelectedValue='<%# Bind("CategoryID") %>' direkt i den deklarativa syntaxen.

Du kan också ange listrutans databindningar genom att redigera mallen via designern och klicka på länken Redigera databindningar från listrutans smarta tagg. Ange sedan att egenskapen SelectedValue ska bindas till fältet CategoryID med hjälp av dubbelriktad databindning (se bild 10). Upprepa antingen den deklarativa processen eller Designer-processen för att binda SupplierID datafältet till Suppliers rullgardinsmenyn.

Binda CategoryID till DropDownList:ens SelectedValue-egenskapen med Two-Way-databindning

Bild 10: Binda CategoryID till listrutans SelectedValue egenskap med hjälp av Two-Way databindning (Klicka om du vill visa en bild i full storlek)

När bindningarna har tillämpats på egenskaperna för SelectedValue de två listrutorna, kommer kolumnerna för kategori och leverantör i den redigerade produkten att som standard använda den aktuella produktens värden. När du klickar på Uppdatera kommer CategoryID- och SupplierID-värdena för det valda alternativet i listrutan att skickas till UpdateProduct-metoden. Bild 11 visar självstudien efter att databindningsinstruktionerna har lagts till. Notera hur listrutealternativen för Chef Antons Cajun Seasoning korrekt är "Condiment" och "New Orleans Cajun Delights".

Den redigerade produktens aktuella kategori- och leverantörsvärden är markerade som standard

Bild 11: Den redigerade produktens aktuella kategori- och leverantörsvärden är markerade som standard (Klicka om du vill visa en bild i full storlek)

Hantering av värdenNULL

Kolumnerna CategoryID och SupplierID i Products-tabellen kan vara NULL, men listrutorna i EditItemTemplate innehåller inte ett listobjekt som representerar ett NULL-värde. Detta har två konsekvenser:

  • Användaren kan inte använda vårt gränssnitt för att ändra en produkts kategori eller leverantör från ett icke-värdeNULL till ett NULL värde
  • Om en produkt har en NULLCategoryID eller SupplierIDresulterar det i ett undantag om du klickar på knappen Redigera. Det beror på att värdet NULL som returneras av CategoryID (eller SupplierID) i -instruktionen Bind() inte mappas till ett värde i listrutan (listrutan genererar ett undantag när dess SelectedValue egenskap är inställd på ett värde som inte finns i dess samling med listobjekt).

För att stödja NULLCategoryID och SupplierID värden måste vi lägga till ytterligare en ListItem till varje listruta för att representera NULL värdet. I självstudien Master/Detail Filtering With a DropDownList (Huvud-/detaljfiltrering med en listruta) såg vi hur man lägger till en ytterligare ListItem till en databunden listruta, vilket innebar att ställa in DropDownList-egenskapen AppendDataBoundItems till True och manuellt lägga till den ytterligare ListItem. I den föregående tutorialen har vi dock lagt till en ListItem med en Value med -1. Databindningslogik i ASP.NET konverterar dock automatiskt en tom sträng till ett NULL värde och vice versa. Därför vill vi att ListItems Value ska vara en tom sträng i den här självstudien.

Börja med att ställa in egenskapen AppendDataBoundItems för båda DropDownLists till True. Lägg sedan till NULLListItem genom att lägga till följande <asp:ListItem>-element i varje DropDownList så att den deklarativa markeringen ser ut så här:

<asp:DropDownList ID="Categories" runat="server"
    DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
    DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'
    AppendDataBoundItems="True">
    <asp:ListItem Value="">(None)</asp:ListItem>
</asp:DropDownList>

Jag har valt att använda "(None)" som textvärde för detta ListItem, men du kan ändra det till att även vara en tom sträng om du vill.

Anmärkning

Som vi såg i självstudien ListItem) kan du lägga till s i en listruta via designern genom att klicka på egenskapen DropDownList i fönstret Egenskaper (som visar Items samlingsredigerarenListItem). Se till att lägga till den här självstudien NULLListItem via den deklarativa syntaxen. Om du använder ListItem samlingsredigeraren utelämnar den genererade deklarativa syntaxen Value inställningen helt och hållet när den tilldelas en tom sträng, vilket skapar deklarativ markering som: <asp:ListItem>(None)</asp:ListItem>. Även om detta kan se ofarligt ut gör det saknade värdet att listrutan använder egenskapsvärdet Text istället. Det innebär att om detta NULLListItem väljs kommer värdet "(None)" att försöka tilldelas till CategoryID, vilket resulterar i ett undantag. Genom att uttryckligen ange Value=""tilldelas ett NULL värde till CategoryID när NULLListItem är markerat.

Upprepa de här stegen för listrutan Leverantörer.

Med detta ytterligare ListItemkan redigeringsgränssnittet nu tilldela NULL värden till en produkts CategoryID och SupplierID fält, som visas i bild 12.

Välj (Ingen) för att tilldela ett NULL-värde för en produkts kategori eller leverantör

Bild 12: Välj (Ingen) för att tilldela ett NULL värde för en produkts kategori eller leverantör (Klicka om du vill visa en bild i full storlek)

Steg 4: Använda RadioButtons för den utgångna statusen

För närvarande uttrycks produkternas Discontinued datafält med hjälp av en CheckBoxField, som återger en inaktiverad kryssruta för de skrivskyddade raderna och en aktiverad kryssruta för raden som redigeras. Även om det här användargränssnittet ofta är lämpligt kan vi anpassa det om det behövs med hjälp av ett TemplateField. I den här självstudien ska vi ändra CheckBoxField till ett TemplateField som använder en RadioButtonList-kontroll med två alternativ "Active" och "Discontinued" från vilka användaren kan ange produktens Discontinued värde.

Börja med att konvertera Discontinued CheckBoxField till ett TemplateField, vilket skapar ett TemplateField med ett ItemTemplate och ett EditItemTemplate. Båda mallarna innehåller en kryssruta med sin Checked-egenskap bunden till Discontinued-datafältet, den enda skillnaden mellan de två är att CheckBoxens ItemTemplate-egenskap är inställd på Enabled.

Ersätt kryssrutan ItemTemplate i både och EditItemTemplate med en RadioButtonList-kontroll och ange båda RadioButtonLists ID egenskaper till DiscontinuedChoice. Ange sedan att alternativknappslistor ska innehålla två alternativknappar, en märkt "Aktiv" med värdet "False", och en märkt "Discontinued" med värdet "True". För att åstadkomma detta kan du antingen ange elementen <asp:ListItem> direkt via den deklarativa syntaxen eller använda ListItem samlingsredigeraren från designern. Bild 13 visar ListItem Samlingsredigeraren efter att de två radioknappsalternativen har angetts.

Lägg till aktiva och utgångna alternativ i RadioButtonList

Bild 13: Lägg till aktiva och utgångna alternativ i RadioButtonList (Klicka om du vill visa en bild i full storlek)

Eftersom RadioButtonList i ItemTemplate borde inte vara redigerbar anger du dess Enabled egenskap till Falseoch lämnar Enabled egenskapen till True (standard) för RadioButtonList i EditItemTemplate. Detta gör att alternativknapparna i den icke-redigerade raden blir endast läsbara, men användaren kan ändra värdena på alternativknapparna för den redigerade raden.

Vi måste fortfarande tilldela egenskaperna för RadioButtonList-kontrollerna SelectedValue så att lämplig alternativknapp väljs baserat på produktens Discontinued datafält. Precis som med listrutorna som granskats tidigare i handledningen kan databindningssyntaxen antingen läggas till direkt i den deklarativa markeringen eller via "Redigera dataförbindelser"-länken i RadioButtonLists' smarta taggar.

När du har lagt till de två RadioButtonLists och konfigurerat dem Discontinued bör TemplateFields deklarativa markering se ut så här:

<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
    <ItemTemplate>
        <asp:RadioButtonList ID="DiscontinuedChoice" runat="server"
          Enabled="False" SelectedValue='<%# Bind("Discontinued") %>'>
            <asp:ListItem Value="False">Active</asp:ListItem>
            <asp:ListItem Value="True">Discontinued</asp:ListItem>
        </asp:RadioButtonList>
    </ItemTemplate>
    <EditItemTemplate>
        <asp:RadioButtonList ID="DiscontinuedChoice" runat="server"
            SelectedValue='<%# Bind("Discontinued") %>'>
            <asp:ListItem Value="False">Active</asp:ListItem>
            <asp:ListItem Value="True">Discontinued</asp:ListItem>
        </asp:RadioButtonList>
    </EditItemTemplate>
</asp:TemplateField>

Med dessa ändringar Discontinued har kolumnen omvandlats från en lista med kryssrutor till en lista över alternativknapppar (se bild 14). När du redigerar en produkt väljs lämplig alternativknapp och produktens utgångna status kan uppdateras genom att välja den andra alternativknappen och klicka på Uppdatera.

De utgångna kryssrutorna har ersatts av radioknappspar

Bild 14: De borttagna kryssrutorna har ersatts av alternativknapppar (klicka om du vill visa en bild i full storlek)

Anmärkning

Discontinued Eftersom kolumnen i Products databasen inte kan ha NULL värden behöver vi inte bry oss om att samla in NULL information i gränssnittet. Discontinued Om kolumnen däremot kan innehålla NULL värden skulle vi vilja lägga till en tredje alternativknapp i listan med dess Value inställd på en tom sträng (Value=""), precis som med kategorin och leverantörens rullgardinsmenyer.

Sammanfattning

Även om BoundField och CheckBoxField automatiskt renderar skrivskyddade, redigerings- och infogningsgränssnitt, saknar de möjlighet till anpassning. Men ofta behöver vi anpassa redigerings- eller infogningsgränssnittet, kanske lägga till valideringskontroller (som vi såg i föregående självstudie) eller genom att anpassa användargränssnittet för datainsamling (som vi såg i den här självstudien). Anpassning av gränssnittet med ett TemplateField kan sammanfattas i följande steg:

  1. Lägg till ett TemplateField eller konvertera ett befintligt BoundField eller CheckBoxField till ett TemplateField
  2. Utöka gränssnittet efter behov
  3. Binda lämpliga datafält till de nyligen tillagda webbkontrollerna med hjälp av dubbelriktad databindning

Förutom att använda de inbyggda ASP.NET webbkontrollerna kan du även anpassa mallarna för ett TemplateField med anpassade, kompilerade serverkontroller och användarkontroller.

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.