Udostępnij za pośrednictwem


Dostosowywanie interfejsu modyfikacji danych (VB)

Autor : Scott Mitchell

Pobierz plik PDF

W tym samouczku przyjrzymy się, jak dostosować interfejs edytowalnego obiektu GridView, zastępując standardowe kontrolki TextBox i CheckBox alternatywnymi kontrolkami wejściowymi sieci Web.

Wprowadzenie

Kontrolki BoundFields i CheckBoxFields używane przez GridView i DetailsView upraszczają proces modyfikacji danych dzięki możliwości renderowania interfejsów w trybie tylko do odczytu, edytowalnym i z możliwością wstawiania. Te interfejsy można renderować bez konieczności dodawania dodatkowych znaczników deklaratywnych lub kodu. Jednak interfejsy BoundField i CheckBoxField nie mają możliwości dostosowywania często potrzebne w rzeczywistych scenariuszach. Aby dostosować interfejs do edycji lub wstawiania w GridView lub DetailsView, należy zamiast tego użyć TemplateField.

W poprzednim samouczku pokazaliśmy, jak dostosować interfejsy modyfikacji danych przez dodanie kontrolek walidacyjnych sieci Web. W tym samouczku przyjrzymy się, jak dostosować kontrolki sieci Web do gromadzenia danych, zastępując kontrolki BoundField i CheckBoxField alternatywnymi kontrolkami wejściowymi. W szczególności utworzymy edytowalną strukturę GridView, która umożliwia aktualizację nazwy produktu, kategorii, dostawcy oraz statusu wycofaniu z produkcji. Podczas edytowania określonego wiersza pola kategorii i dostawcy będą renderowane jako Listy rozwijane, zawierające zestaw dostępnych kategorii i dostawców do wyboru. Ponadto zastąpimy domyślną kontrolkę CheckBoxField kontrolką RadioButtonList, która oferuje dwie opcje: "Aktywne" i "Przerwane".

Interfejs edycji kontrolki GridView zawiera listy rozwijane i przyciski radiowe

Rysunek 1. Interfejs edycji kontrolki GridView zawiera listy rozwijane i przyciski radiowe (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Krok 1. Tworzenie odpowiedniegoUpdateProductprzeciążenia

W tym samouczku utworzymy edytowalny widok siatki GridView, który umożliwia edytowanie nazwy produktu, kategorii, dostawcy oraz statusu jego wycofania z rynku. W związku z tym potrzebujemy UpdateProduct przeciążenia, które przyjmuje pięć parametrów: cztery wartości produktu, plus ProductID. Podobnie jak w poprzednich przeciążeniach, będzie to:

  1. Pobierz informacje o produkcie z bazy danych dla określonego ProductID.
  2. Aktualizuj pola ProductName, CategoryID, SupplierID i Discontinued
  3. Wyślij żądanie aktualizacji do DAL za pomocą metody Update() TableAdapter.

Dla zwięzłości, w tym konkretnym przeciążeniu pominąłem sprawdzanie reguły biznesowej, która zapewnia, że oznaczenie produktu jako wycofanego nie oznacza, że jest on jedynym produktem oferowanym przez swojego dostawcę. Możesz go dodać, jeśli wolisz lub, najlepiej, refaktoryzować logikę do oddzielnej metody.

Poniższy kod przedstawia nowe przeciążenie UpdateProduct w klasie 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

Krok 2. Tworzenie edytowalnego obiektu GridView

Po dodaniu przeciążenia UpdateProduct jesteśmy gotowi, aby utworzyć edytowalny GridView. Otwórz stronę CustomizedUI.aspx w folderze EditInsertDelete i dodaj kontrolkę GridView do Designer. Następnie utwórz nowy obiekt ObjectDataSource na podstawie tagu inteligentnego GridView. Skonfiguruj obiekt ObjectDataSource, aby pobrać informacje o produkcie za pośrednictwem metodą klasy GetProducts() i zaktualizować dane produktu przy użyciu właśnie utworzonego przeciążenia UpdateProduct. Na kartach INSERT i DELETE wybierz pozycję (Brak) z list rozwijanych.

Konfigurowanie obiektu ObjectDataSource do używania właśnie utworzonego przeciążenia UpdateProduct

Rysunek 2. Konfigurowanie obiektu ObjectDataSource do używania właśnie utworzonego UpdateProduct przeciążenia (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Jak pokazano w samouczkach dotyczących modyfikacji danych, składnia deklaratywna dla obiektu ObjectDataSource utworzonego przez program Visual Studio przypisuje właściwość OldValuesParameterFormatString do elementu original_{0}. Oczywiście nie będzie to działać z naszą warstwą logiki biznesowej, ponieważ nasze metody nie oczekują przekazania oryginalnej ProductID wartości. W związku z tym, jak to robiliśmy w poprzednich samouczkach, poświęć chwilę, aby usunąć przypisanie tej właściwości w składni deklaratywnej lub, zamiast tego, ustaw tę właściwość na wartość {0}.

Po tej zmianie znacznik deklaratywny objectDataSource powinien wyglądać następująco:

<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>

Należy pamiętać, że właściwość OldValuesParameterFormatString została usunięta i że w kolekcji UpdateParameters znajduje się element Parameter dla każdego z parametrów wejściowych oczekiwanych przez nasze przeciążenie UpdateProduct.

Podczas gdy obiekt ObjectDataSource jest skonfigurowany do aktualizowania tylko podzestawu wartości produktu, kontrolka GridView obecnie wyświetla wszystkie pola produktu. Poświęć chwilę na edycję GridView, aby:

  • Obejmuje tylko pola ProductName, SupplierName, CategoryName BoundFields oraz Discontinued CheckBoxField
  • Pola CategoryName i SupplierName powinny pojawić się przed (po lewej stronie) polem Discontinued CheckBoxField
  • Właściwość CategoryName i SupplierName BoundFields HeaderText jest ustawiona odpowiednio na "Category" i "Supplier"
  • Obsługa edycji jest włączona (zaznacz pole wyboru Włącz edytowanie w tagu inteligentnym GridView)

Po tych zmianach Designer będzie wyglądać podobnie do rysunku 3, z deklaratywną składnią GridView pokazana poniżej.

Usuwanie niepotrzebnych pól z kontrolki GridView

Rysunek 3. Usuwanie niepotrzebnych pól z widoku GridView (kliknij, aby wyświetlić obraz pełnowymiarowy)

<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>

W tym momencie działanie kontrolki GridView tylko do odczytu zostało ukończone. Podczas wyświetlania danych każdy produkt jest renderowany jako wiersz w GridView, pokazując nazwę produktu, kategorię, dostawcę i status wycofania.

Interfejs Read-Only GridView został ukończony

Rysunek 4. Interfejs Read-Only GridView został ukończony (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Jak opisano w artykule Omówienie wstawiania, aktualizowania i usuwania danych, ważne jest, aby stan widoku gridView był włączony (zachowanie domyślne). Jeśli ustawisz właściwość GridView EnableViewState na wartość false, istnieje ryzyko przypadkowego usunięcia lub edytowania rekordów przez równocześnie działających użytkowników.

Krok 3: Stosowanie listy rozwijanej dla interfejsów edycji kategorii i dostawców

Pamiętaj, że obiekt ProductsRow zawiera właściwości CategoryID, CategoryName, SupplierID i SupplierName, które podają rzeczywiste wartości identyfikatorów kluczy obcych w tabeli Products oraz odpowiadające wartości Name w tabelach Categories i Suppliers. Wartości ProductRow, CategoryID i SupplierID mogą być zarówno odczytywane, jak i zapisywane, natomiast właściwości CategoryName i SupplierName są oznaczone jako tylko do odczytu.

Ze względu na stan właściwości CategoryName i SupplierName jako tylko do odczytu, odpowiednie pola BoundFields mają ustawioną właściwość ReadOnly na True, co uniemożliwia modyfikowanie tych wartości podczas edycji wiersza. Chociaż możemy ustawić właściwość ReadOnly na False, renderowanie pól CategoryName i SupplierName BoundFields jako TextBoxes podczas edycji spowoduje wyjątek, gdy użytkownik próbuje zaktualizować produkt, ponieważ nie ma przeciążenia UpdateProduct, które przyjmuje dane wejściowe CategoryName i SupplierName. W rzeczywistości nie chcemy tworzyć takiego przeciążenia z dwóch powodów:

  • Tabela Products nie ma SupplierName ani CategoryName pól, ale SupplierID i CategoryID. W związku z tym chcemy, aby do naszej metody zostały przekazane te konkretne wartości identyfikatorów, a nie wartości z ich tabel odnośników.
  • Wymaganie od użytkownika wpisania nazwy dostawcy lub kategorii jest mniejsze niż idealne, ponieważ wymaga od użytkownika znajomości dostępnych kategorii i dostawców oraz ich poprawnych pisowni.

Pola dostawca i kategoria powinny wyświetlać nazwy kategorii i dostawców w trybie tylko do odczytu (tak jak teraz) oraz listę rozwijaną odpowiednich opcji podczas edycji. Korzystając z listy rozwijanej, użytkownik końcowy może szybko zobaczyć, jakie kategorie i dostawcy są dostępne do wyboru, i może łatwiej dokonać wyboru.

Aby zapewnić to zachowanie, musimy przekonwertować SupplierName oraz CategoryName z BoundFields na TemplateFields, których ItemTemplate emituje wartości SupplierName oraz CategoryName, a których EditItemTemplate używa kontrolka DropDownList do wyświetlania listy dostępnych kategorii i dostawców.

Dodawanie listCategoriesrozwijanych iSuppliers

Zacznij od przekonwertowania pól SupplierName i CategoryName BoundFields na Pola szablonów, klikając link Edytuj kolumny z tagu inteligentnego GridView, wybierając pole BoundField z listy w lewym dolnym rogu, a następnie klikając link "Konwertuj to pole na pole szablonu". Proces konwersji utworzy pole szablonu z wartością ItemTemplate i EditItemTemplate, jak pokazano w poniższej składni deklaratywnej:

<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>

Ponieważ pole BoundField zostało oznaczone jako tylko do odczytu, zarówno ItemTemplate, jak i EditItemTemplate zawiera kontrolkę sieci Web Label, której Text właściwość jest powiązana z odpowiednim polem danych (CategoryName, w składni powyżej). Musimy zmodyfikować kontrolkę EditItemTemplate, zastępując kontrolkę Label kontrolką DropDownList.

Jak widzieliśmy w poprzednich samouczkach, szablon można edytować za pomocą projektanta lub bezpośrednio ze składni deklaratywnej. Aby edytować go za pomocą projektanta, kliknij link Edytuj szablony z tagu inteligentnego GridView i wybierz pracę z polem EditItemTemplateKategoria. Usuń kontrolkę Label Web i zastąp ją kontrolką DropDownList, ustawiając właściwość ID kontrolki DropDownList na Categories.

Usuń pole TexBox i dodaj listę rozwijaną do elementu EditItemTemplate

Rysunek 5: Usuń pole TexBox i dodaj listę rozwijaną do EditItemTemplate (kliknij, aby wyświetlić obraz pełnowymiarowy)

Następnie musimy wypełnić listę DropDownList dostępnymi kategoriami. Kliknij link Wybierz źródło danych z tagu inteligentnego Listy rozwijanej i wybierz opcję utworzenia nowego obiektu ObjectDataSource o nazwie CategoriesDataSource.

Tworzenie nowej kontrolki ObjectDataSource o nazwie CategoriesDataSource

Rysunek 6. Tworzenie nowej kontrolki ObjectDataSource o nazwie CategoriesDataSource (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Aby obiekt ObjectDataSource zwrócił wszystkie kategorie, powiąż go z CategoriesBLL metodą klasy GetCategories() .

Wiązanie obiektu ObjectDataSource z metodą GetCategories() kategoriiBLL

Rysunek 7: Powiąż ObjectDataSource z metodą CategoriesBLLGetCategories() (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Na koniec skonfiguruj ustawienia listy rozwijanej DropDownList, tak aby pole CategoryName było wyświetlane w każdej liście rozwijanej DropDownList, z polem CategoryID używanym jako wartość.

Wyświetl pole CategoryName i użyj identyfikatora CategoryID jako wartości

Rysunek 8: Pole CategoryName wyświetlane i CategoryID używane jako wartość (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Po wprowadzeniu tych zmian znaczniki deklaratywne dla EditItemTemplate elementu w CategoryName polu TemplateField będą zawierać zarówno listę rozwijaną, jak i obiekt 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>

Uwaga

DropDownList w EditItemTemplate musi mieć włączony stan widoku. Wkrótce dodamy składnię powiązania danych do deklaratywnej składni listy DropDownList, a polecenia powiązania danych, takie jak Eval() i Bind(), mogą pojawić się wyłącznie w kontrolkach, w których stan widoku jest włączony.

Powtórz te kroki, aby dodać listę rozwijaną DropDownList nazwaną Suppliers do pola szablonu SupplierNameEditItemTemplate. Spowoduje to dodanie listy rozwijanej do EditItemTemplate i utworzenie kolejnego ObjectDataSource. Należy jednak skonfigurować źródło danych Suppliers DropDownList tak, aby wywoływało metodę GetSuppliers() klasy SuppliersBLL. Ponadto skonfiguruj listę rozwijaną Suppliers DropDownList, aby wyświetlała pole CompanyName i używała pola SupplierID jako wartości jego ListItem.

Po dodaniu DropDownLists do dwóch EditItemTemplate-ów, załaduj stronę w przeglądarce i kliknij przycisk Edytuj dla produktu Chef Anton's Cajun Seasoning. Jak pokazano na rysunku 9, kolumny kategorii i dostawcy produktu są renderowane jako listy rozwijane zawierające dostępne kategorie i dostawców do wyboru. Należy jednak pamiętać, że pierwsze pozycje na obu listach rozwijanych są wybierane domyślnie (Napoje jako kategorię i Egzotyczne napoje jako dostawcę), nawet jeśli przyprawa Chef Anton's Cajun Seasoning jest dostarczana przez New Orleans Cajun Delights.

Pierwszy element na listach Drop-Down jest domyślnie wybierany

Rysunek 9. Pierwszy element na listach Drop-Down jest domyślnie wybierany (kliknij, aby wyświetlić obraz pełnowymiarowy)

pl-PL: Ponadto, po kliknięciu przycisku Aktualizuj, zobaczysz, że wartości CategoryID i SupplierID produktu są ustawione na wartość NULL. Oba te niepożądane zachowania są spowodowane tym, że listy rozwijane w EditItemTemplate nie są powiązane z żadnymi polami danych z danych źródłowych produktu.

Wiązanie list rozwijanych z polamiCategoryIDdanych iSupplierID

Aby listy rozwijane dla edytowanego produktu były ustawione na odpowiednie wartości i aby te wartości były przesyłane z powrotem do metody BLL UpdateProduct po kliknięciu Aktualizuj, musimy powiązać właściwości SelectedValue list rozwijanych z polami danych CategoryID i SupplierID, używając dwukierunkowego powiązania danych. Aby to osiągnąć za pomocą Categories DropDownList, możesz dodać SelectedValue='<%# Bind("CategoryID") %>' bezpośrednio do składni deklaratywnej.

Alternatywnie, można ustawić powiązania danych menu rozwijalnego DropDownList, edytując szablon w Designerze i klikając polecenie Edytuj powiązania danych z inteligentnego tagu DropDownList. Następnie wskaż, że SelectedValue właściwość powinna być powiązana z CategoryID polem przy użyciu dwukierunkowego powiązania danych (zobacz Rysunek 10). Powtórz proces deklaratywny lub proces Projektanta, aby powiązać pole danych SupplierID z listą rozwijaną Suppliers.

Powiąż identyfikator CategoryID z właściwością SelectedValue listy rozwijanej przy użyciu Two-Way powiązania danych

Rysunek 10: Powiąż CategoryID z właściwością SelectedValue kontrolki DropDownList używając powiązania danych Two-Way (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Po zastosowaniu powiązań do właściwości SelectedValue dwóch list rozwijanych, kolumny kategorii i dostawcy edytowanego produktu będą domyślnie przyjmować wartości bieżącego produktu. Po kliknięciu Aktualizuj wartości CategoryID oraz SupplierID wybranego elementu listy rozwijanej zostaną przekazane do metody UpdateProduct. Rysunek 11 przedstawia samouczek po dodaniu instrukcji powiązania danych; zwróć uwagę, jak wybrane elementy listy rozwijanej dla przypraw Chef Anton's Cajun Seasoning są prawidłowo skategoryzowane jako przyprawy i New Orleans Cajun Delights.

Wartości bieżącej kategorii i dostawcy edytowanego produktu są domyślnie wybrane

Rysunek 11. Edytowana kategoria i wartości dostawców produktu są domyślnie wybrane (kliknij, aby wyświetlić obraz pełnowymiarowy)

ObsługaNULLwartości

Kolumny CategoryID i SupplierID w tabeli Products mogą mieć NULL wartość, ale listy rozwijane w EditItemTemplate nie zawierają elementu listy do reprezentowania wartości NULL. Ma to dwie konsekwencje:

  • Użytkownik nie może użyć naszego interfejsu, aby zmienić kategorię lub dostawcę produktu z wartości innej niż NULL na NULL
  • Jeśli produkt ma wartość NULLCategoryID lub SupplierID, kliknięcie przycisku Edytuj spowoduje wyjątek. Jest to spowodowane tym, że wartość NULL zwracana przez CategoryID (lub SupplierID) w instrukcji Bind() nie jest mapowana na wartość w Liście rozwijanej (Lista rozwijana zgłasza wyjątek, gdy właściwość SelectedValue jest ustawiona na wartość nie zawartą w kolekcji elementów listy).

Aby obsługiwać wartości NULL, CategoryID i SupplierID, musimy dodać kolejny element ListItem do każdej listy rozwijanej, aby reprezentować wartość NULL. W samouczku Master/Detail Filtering With a DropDownList zobaczyliśmy, jak dodać dodatkowy ListItem do powiązanej z danymi listy rozwijanej DropDownList, co obejmowało ustawienie właściwości AppendDataBoundItems na True i ręczne dodanie dodatkowego ListItem. W tym poprzednim samouczku dodaliśmy jednak element ListItem z wartością Value-1. Logika powiązania danych w ASP.NET jednak automatycznie konwertuje pusty ciąg na NULL wartość i odwrotnie. W związku z tym na potrzeby tego samouczka chcemy, aby ListItem ciąg Value był pusty.

Zacznij od ustawienia właściwości obu list rozwijanych AppendDataBoundItems na True. Następnie dodaj komponent NULLListItem, dołączając następujący element <asp:ListItem> do każdej listy rozwijanej, aby znaczniki deklaratywne wyglądały jak poniżej:

<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>

Wybrano opcję użycia wartości "(None)" jako wartości Text dla tego ListItemelementu , ale można ją zmienić tak, aby była również pustym ciągiem, jeśli chcesz.

Uwaga

Jak pokazano w samouczku Master/Detail Filtering With a DropDownList (Filtrowanie wzorca/szczegółów z listą rozwijaną), elementy można dodać do listy rozwijanej za pośrednictwem Projektanta, klikając na właściwość ListItem listy rozwijanej w oknie Właściwości (w którym zostanie wyświetlony Items Edytor kolekcji). ListItem Jednak pamiętaj, aby dodać NULLListItem do tego samouczka za pomocą składni deklaratywnej. Jeśli używasz ListItem Edytora Kolekcji, wygenerowana składnia deklaratywna całkowicie pominie ustawienie Value po przypisaniu pustego ciągu, tworząc znacznik deklaratywny, taki jak: <asp:ListItem>(None)</asp:ListItem>. Chociaż może to wyglądać nieszkodliwie, brakująca wartość powoduje, że DropDownList używa wartości właściwości Text jako zamiennik. Oznacza to, że w przypadku wybrania tej NULLListItem wartości zostanie podjęta próba przypisania CategoryIDwartości "(None)", co spowoduje wyjątek. Jawne ustawienie Value="" spowoduje przypisanie wartości NULL do CategoryID po wybraniu NULLListItem.

Powtórz te kroki dla listy rozwijanej Dostawcy.

Dzięki temu dodatkowemu ListItem interfejsowi edycji można teraz przypisywać wartości NULL do pól produktu CategoryID i SupplierID, jak pokazano na rysunku 12.

Wybierz pozycję (Brak), aby przypisać wartość NULL dla kategorii lub dostawcy produktu

Rysunek 12. Wybierz pozycję (Brak), aby przypisać NULL wartość dla kategorii lub dostawcy produktu (kliknij, aby wyświetlić obraz pełnowymiarowy)

Krok 4: Używanie przycisków radiowych dla stanu wycofanego

Obecnie pole danych produktów Discontinued jest wyrażane przy użyciu pola CheckBoxField, które renderuje wyłączone pole wyboru dla wierszy tylko do odczytu i włączone pole wyboru dla edytowanego wiersza. Chociaż ten interfejs użytkownika jest często odpowiedni, możemy dostosować go w razie potrzeby przy użyciu pola szablonu. W tym samouczku zmieńmy pole CheckBoxField na pole szablonu, które używa kontrolki RadioButtonList z dwiema opcjami "Aktywne" i "Przerwane", z których użytkownik może określić wartość produktu Discontinued .

Zacznij od przekonwertowania pola Discontinued CheckBoxField na pole szablonu, które spowoduje utworzenie pola szablonu z elementem ItemTemplate i EditItemTemplate. Oba szablony zawierają pole wyboru CheckBox, którego właściwość Checked jest powiązana z polem danych Discontinued. Jedyną różnicą między nimi jest to, że w szablonie ItemTemplate właściwość CheckBox Enabled jest ustawiona na wartość False.

Zastąp pole wyboru zarówno w ItemTemplate jak i EditItemTemplate kontrolką RadioButtonList, ustawiając właściwość kontrolki RadioButtonList ID na wartość DiscontinuedChoice. Następnie należy wskazać, że każdy element RadioButtonLists powinien zawierać dwa przyciski radiowe: jeden z etykietą "Active" i wartością "False" oraz drugi z etykietą "Discontinued" i wartością "True". Aby to osiągnąć, możesz wprowadzić <asp:ListItem> elementy bezpośrednio za pomocą składni deklaratywnej lub użyć ListItem Edytora kolekcji Projektanta. Rysunek 13 przedstawia ListItem Edytor kolekcji po określeniu dwóch opcji przycisku radiowego.

Dodaj opcje aktywne i nieaktywne do listy RadioButtonList

Rysunek 13. Dodawanie opcji aktywnych i nieaktywnych do listy RadioButtonList (kliknij, aby wyświetlić obraz pełnowymiarowy)

Ponieważ właściwość RadioButtonList w elemecie ItemTemplate nie powinna być edytowalna, ustaw jej Enabled właściwość na False, pozostawiając Enabled właściwość na True (wartość domyślną) dla elementu RadioButtonList w obiekcie EditItemTemplate. Spowoduje to, że przyciski radiowe w nieedytowanym wierszu będą tylko do odczytu, ale użytkownik będzie mógł zmieniać wartości przycisków radiowych w edytowanym wierszu.

Nadal musimy przypisać właściwości kontrolek SelectedValue RadioButtonList, aby odpowiedni przycisk radiowy był wybierany na podstawie pola danych produktu Discontinued . Podobnie jak w przypadku elementów DropDownLists, które zostały zbadane wcześniej w tym samouczku, składnia powiązania danych może zostać dodana bezpośrednio do tagów deklaratywnych lub za pośrednictwem linku Edit DataBindings w tagach inteligentnych RadioButtonLists.

Po dodaniu dwóch elementów RadioButtonLists i skonfigurowaniu ich, deklaratywne znaczniki TemplateField będą wyglądać następująco: Discontinued

<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>

Dzięki tym zmianom kolumna Discontinued została przekształcona z listy pól wyboru na listę par przycisków radiowych (zobacz Rysunek 14). Podczas edytowania produktu należy wybrać odpowiedni przycisk radiowy, a stan wycofania produktu może zostać zaktualizowany po wybraniu innego przycisku radiowego i kliknięciu Aktualizuj.

Wycofane pola wyboru zostały zastąpione przez pary przycisków radiowych

Rysunek 14. Wycofane pola wyboru zostały zastąpione przez pary przycisków radiowych (kliknij, aby wyświetlić obraz pełnowymiarowy)

Uwaga

Ponieważ kolumna Discontinued w Products bazie danych nie może zawierać NULL wartości, nie musimy martwić się o przechwytywanie NULL informacji w interfejsie. Gdyby jednak kolumna Discontinued mogła zawierać NULL wartości, chcemy dodać trzeci przycisk radiowy do listy z atrybutem Value ustawionym na pusty ciąg znaków (Value=""), podobnie jak w przypadku list rozwijanych dla kategorii i dostawców.

Podsumowanie

Chociaż BoundField i CheckBoxField automatycznie renderują interfejsy do odczytu, edytowania i wstawiania, brakuje im możliwości dostosowywania. Często jednak musimy dostosować interfejs edytowania lub wstawiania, być może dodanie kontrolek weryfikacji (jak pokazano w poprzednim samouczku) lub dostosowanie interfejsu użytkownika zbierania danych (jak pokazano w tym samouczku). Dostosowywanie interfejsu za pomocą pola TemplateField można podsumować w następujących krokach:

  1. Dodawanie pola szablonu lub konwertowanie istniejącego pola BoundField lub CheckBoxField na pole szablonu
  2. Rozszerzanie interfejsu zgodnie z potrzebami
  3. Wiązanie odpowiednich pól danych z nowo dodanymi kontrolkami sieci Web przy użyciu dwukierunkowego powiązania danych

Oprócz używania wbudowanych kontrolek sieciowych ASP.NET, można również dostosować szablony TemplateField za pomocą niestandardowych, skompilowanych kontrolek serwera i kontrolek użytkownika.

Szczęśliwe programowanie!

Informacje o autorze

Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można go uzyskać pod adresem mitchell@4GuysFromRolla.com.