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 kontrolki GridView i DetailsView upraszczają proces modyfikowania danych ze względu na możliwość renderowania interfejsów tylko do odczytu, edytowalnych i 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ć edytowalny lub wstawiany interfejs w elementy GridView lub DetailsView, należy zamiast tego użyć pola szablonu.

W poprzednim samouczku pokazano, jak dostosować interfejsy modyfikacji danych przez dodanie kontrolek sieci Web walidacji. W tym samouczku przyjrzymy się, jak dostosować rzeczywiste kontrolki sieci Web zbierania danych, zastępując standardowe kontrolki TextBox i CheckBoxField standardową kontrolką TextBox i CheckBox pola alternatywnymi kontrolkami wejściowymi sieci Web. W szczególności utworzymy edytowalny element GridView, który umożliwia aktualizację nazwy, kategorii, dostawcy i stanu produktu. 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 element GridView, który umożliwia edytowanie nazwy, kategorii, dostawcy i stanu produktu. W związku z tym potrzebujemy UpdateProduct przeciążenia, które akceptuje pięć parametrów wejściowych tych czterech wartości produktu oraz ProductID. Podobnie jak w poprzednich przeciążeniach, będzie to:

  1. Pobierz informacje o produkcie z bazy danych dla określonego ProductIDelementu ,
  2. ProductNameAktualizowanie pól , CategoryID, SupplierIDi Discontinued
  3. Wyślij żądanie aktualizacji do dal za pomocą metody TableAdapter Update() .

W przypadku zwięzłości tego konkretnego przeciążenia pominięto sprawdzanie reguły biznesowej, które gwarantuje, że produkt jest oznaczony jako zaprzestany, nie jest jedynym produktem oferowanym przez dostawcę. Możesz go dodać, jeśli wolisz lub, najlepiej, refaktoryzować logikę do oddzielnej metody.

Poniższy kod przedstawia nowe UpdateProduct przeciążenie w ProductsBLL klasie:

<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

UpdateProduct Po dodaniu przeciążenia możemy utworzyć edytowalny element GridView. CustomizedUI.aspx Otwórz stronę w folderze EditInsertDelete i dodaj kontrolkę GridView do projektanta. Następnie utwórz nowy obiekt ObjectDataSource na podstawie tagu inteligentnego GridView. Skonfiguruj obiekt ObjectDataSource, aby pobrać informacje o produkcie za pośrednictwem ProductBLL metody klasy GetProducts() i zaktualizować dane produktu przy użyciu właśnie utworzonego UpdateProduct przeciążenia. 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 OldValuesParameterFormatString właściwość do original_{0}elementu . 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 wykonaliśmy w poprzednich samouczkach, pośmiń chwilę, aby usunąć to przypisanie właściwości ze składni deklaratywnej lub, zamiast tego, ustaw wartość tej właściwości na {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 OldValuesParameterFormatString właściwość została usunięta i że istnieje Parameter element w UpdateParameters kolekcji dla każdego parametru wejściowego oczekiwanego przez nasze UpdateProduct przeciążenie.

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

  • Obejmuje tylko pola ProductName, , SupplierNameCategoryName , BoundFields i Discontinued CheckBoxField
  • Pola CategoryName i SupplierName , które mają pojawić się przed (po lewej stronie) Discontinued pola 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 projektant będzie wyglądać podobnie do rysunku 3, a składnia deklaratywna kontrolki 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 elementy GridView, pokazując nazwę produktu, kategorię, dostawcę i stan przerwania.

Interfejs gridView tylko do odczytu jest ukończony

Rysunek 4. Interfejs tylko do odczytu kontrolki GridView został ukończony (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

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 falsewartość , wystąpi ryzyko przypadkowego usunięcia lub edytowania rekordów przez współbieżnych użytkowników.

Krok 3. Używanie listy rozwijanej dla interfejsów edycji kategorii i dostawcy

Pamiętaj, że ProductsRow obiekt zawiera CategoryIDwłaściwości , CategoryName, SupplierIDi SupplierName , które zapewniają rzeczywiste wartości identyfikatora klucza obcego w Products tabeli bazy danych oraz odpowiednie Name wartości w Categories tabelach i Suppliers . Wartości ProductRowi CategoryID SupplierID mogą być odczytywane z i zapisywane do, natomiast CategoryName właściwości i SupplierName są oznaczone jako tylko do odczytu.

Ze względu na stan CategoryName tylko do odczytu właściwości i SupplierName odpowiednie pola ograniczenia mają ustawioną ReadOnly Truewłaściwość na , co uniemożliwia modyfikowanie tych wartości podczas edycji wiersza. Chociaż możemy ustawić ReadOnly właściwość na False, renderowanie CategoryName pól i SupplierName BoundFields jako TextBoxes podczas edycji, takie podejście spowoduje wyjątek, gdy użytkownik próbuje zaktualizować produkt, ponieważ nie UpdateProduct ma przeciążenia, które pobiera CategoryName i SupplierName wprowadza dane wejściowe. 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 nasza metoda została przekazana tych konkretnych wartości identyfikatorów, a nie ich wartości 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ć wartości SupplierName i BoundFields na TemplateFields, których ItemTemplate emituje SupplierName wartości i CategoryName i, których EditItemTemplate używa kontrolki DropDownList, aby wyświetlić listę dostępnych kategorii i CategoryName 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 kontrolka i EditItemTemplate zawiera kontrolkę sieci Web Etykieta, której Text właściwość jest powiązana z odpowiednim polem danych (CategoryNamew składni powyżej). Musimy zmodyfikować kontrolkę , zastępując kontrolkę Etykieta EditItemTemplateinternetowa 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ę Etykieta sieci Web i zastąp ją kontrolką DropDownList, ustawiając właściwość Identyfikator listy Rozwijanej na Categorieswartość .

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

Rysunek 5. Usuwanie pola TexBox i dodawanie listy rozwijanej do EditItemTemplate listy (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ązanie obiektu ObjectDataSource z CategoriesBLLmetodą "s GetCategories() " (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

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

Wyświetl pole CategoryName i identyfikator CategoryID użyty jako wartość

Rysunek 8. Wyświetlanie CategoryName pola 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

Lista rozwijana na EditItemTemplate liście musi mieć włączony stan widoku. Wkrótce dodamy składnię powiązania danych do deklaratywnej składni listy DropDownList i poleceń powiązania danych, takich jak Eval() i Bind() mogą być wyświetlane tylko w kontrolkach, których stan widoku jest włączony.

Powtórz te kroki, aby dodać listę DropDownList o nazwie Suppliers do pola szablonu EditItemTemplateSupplierName . Spowoduje to dodanie listy rozwijanej EditItemTemplate do obiektu i utworzenie innego obiektu ObjectDataSource. Obiekt Suppliers ObjectDataSource listy DropDownList należy jednak skonfigurować tak, aby wywoływać SuppliersBLL metodę klasy GetSuppliers() . Ponadto skonfiguruj listę Suppliers DropDownList, aby wyświetlić CompanyName pole i użyć SupplierID pola jako wartości jego ListItem wartości.

Po dodaniu listy DropDownLists do tych dwóch EditItemTemplate elementó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 elementy na obu listach rozwijanych są wybierane domyślnie (Napoje dla kategorii i Egzotyczne płyny jako dostawca), mimo że Chef Anton's Cajun Seasoning jest condiment dostarczony przez New Orleans Cajun Delights.

Pierwszy element na listach rozwijanych jest domyślnie wybierany

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

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

Wiązanie list rozwijanych z polamiCategoryIDdanych iSupplierID

Aby edytować listę rozwijaną kategorii i dostawcy produktu ustawioną na odpowiednie wartości i aby te wartości były wysyłane z powrotem do metody BLL UpdateProduct po kliknięciu pozycji Aktualizuj, musimy powiązać właściwości CategoryID Listy rozwijane SelectedValue z polami danych i SupplierID przy użyciu dwukierunkowego powiązania danych. Aby to osiągnąć za pomocą listy Categories DropDownList, możesz dodać SelectedValue='<%# Bind("CategoryID") %>' ją bezpośrednio do składni deklaratywnej.

Alternatywnie można ustawić powiązania danych listy DropDownList, edytując szablon za pomocą Projektanta i klikając link Edytuj elementy DataBindings z tagu inteligentnego Listy rozwijanej. 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 Projektant, aby powiązać SupplierID pole danych z listą rozwijaną Suppliers .

Powiąż identyfikator CategoryID z właściwości SelectedValue listy dropDownList przy użyciu dwukierunkowego powiązania danych

Rysunek 10. Powiązanie CategoryID właściwości listy rozwijanej z SelectedValue dwukierunkowym powiązaniem danych (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Po zastosowaniu powiązań do SelectedValue właściwości dwóch list rozwijanych edytowane kolumny kategorii i dostawcy produktu będą domyślnie domyślnie wartościami bieżącego produktu. Po kliknięciu przycisku Aktualizuj CategoryID wartości i SupplierID wybranego elementu listy rozwijanej zostaną przekazane do UpdateProduct metody . Rysunek 11 przedstawia samouczek po dodaniu instrukcji powiązania danych; Zwróć uwagę, jak wybrane elementy listy rozwijanej dla Chef Anton's Cajun Seasoning są poprawnie Condiment 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 Products tabeli mogą mieć NULLwartość , ale listy rozwijane w EditItemTemplate tabeli nie zawierają elementu listy do reprezentowania NULL wartości. Ma to dwie konsekwencje:

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

Aby obsługiwać NULL CategoryID wartości i SupplierID obsługiwać wartości, musimy dodać kolejny ListItem element do każdej listy Rozwijanej, aby reprezentować NULL wartość. W samouczku Master/Detail Filtering With a DropDownList (Filtrowanie wzorca/szczegółów za pomocą listy rozwijanej DropDownList) zobaczyliśmy, jak dodać dodatkowy element ListItem do listy rozwijanej danych, który obejmował ustawienie właściwości DropDownList AppendDataBoundItems na True wartość i ręczne dodanie dodatkowego ListItemelementu . 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 ListItemchcemy, aby ciąg był Value pusty.

Zacznij od ustawienia właściwości DropDownLists AppendDataBoundItems na Truewartość . Następnie dodaj element NULL ListItem , dodając następujący <asp:ListItem> element do każdej listy Rozwijanej, tak aby znacznik deklaratywny wyglądał następująco:

<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 ( ListItem Filtrowanie wzorca/szczegółów z listą rozwijaną) można dodać do listy rozwijanej za pośrednictwem Projektanta, klikając właściwość DropDownList Items w okno Właściwości (która będzie wyświetlać ListItem Edytor kolekcji). Pamiętaj jednak, aby dodać element do tego samouczka NULL ListItem za pomocą składni deklaratywnej. Jeśli używasz Edytora ListItem kolekcji, wygenerowana składnia deklaratywna całkowicie pominą Value ustawienie 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 lista DropDownList używa Text wartości właściwości w swoim miejscu. Oznacza to, że w przypadku wybrania tej NULL ListItem wartości zostanie podjęta próba przypisania CategoryIDwartości "(None)", co spowoduje wyjątek. Jawnie ustawiając Value=""wartość NULL , zostanie przypisana do CategoryID wartości po wybraniu elementu NULL ListItem .

Powtórz te kroki dla listy rozwijanej Dostawcy.

Dzięki temu dodatkowemu ListIteminterfejsowi edycji można teraz przypisywać NULL wartości do pól i SupplierID produktuCategoryID, 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 przerwanego

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 obejmują pole CheckBox z właściwością Checked powiązaną Discontinued z polem danych. Jedyną różnicą między nimi jest to, że ItemTemplatewłaściwość CheckBox jest ustawiona Enabled na Falsewartość .

Zastąp pole wyboru zarówno w kontrolce , jak ItemTemplate i EditItemTemplate kontrolką RadioButtonList, ustawiając właściwości elementu RadioButtonLists ID na DiscontinuedChoicewartość . Następnie należy wskazać, że kolumny RadioButtonLists powinny zawierać dwa przyciski radiowe, z jedną oznaczoną etykietą "Active" z wartością "False" i jedną oznaczoną etykietą "Discontinued" z 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 w Projektancie. Rysunek 13 przedstawia ListItem Edytor kolekcji po określeniu dwóch opcji przycisku radiowego.

Dodawanie opcji aktywnych i zakończonych 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 ustawienie przycisków radiowych w wierszu nieedytowany jako tylko do odczytu, ale umożliwi użytkownikowi zmianę wartości RadioButton dla edytowanego wiersza.

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 Discontinued znacznik deklaratywny TemplateField powinien wyglądać następująco:

<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 wybrany jest odpowiedni przycisk radiowy, a stan produktu nieumyślnie jest aktualizowany, wybierając inny przycisk radiowy i klikając przycisk 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. Jeśli jednak kolumna może zawierać NULL wartości, Discontinued chcemy dodać trzeci przycisk radiowy do listy z ustawionym Value pustym ciągiem (Value=""), podobnie jak w przypadku kategorii i listy rozwijanej dostawcy.

Podsumowanie

Mimo że interfejsy BoundField i CheckBoxField automatycznie renderują interfejsy tylko do odczytu, edytowania i wstawiania, nie mają 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 ASP.NET Sieci Web można również dostosować szablony pola szablonów z niestandardowymi, skompilowanymi kontrolkami serwera i kontrolkami 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 24 godzinach. Można go uzyskać pod adresem mitchell@4GuysFromRolla.com. lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.