Dodawanie kolumny przycisków radiowych do kontrolki GridView (VB)
W tym samouczku przedstawiono sposób dodawania kolumny przycisków radiowych do kontrolki GridView w celu zapewnienia użytkownikowi bardziej intuicyjnego sposobu wybierania pojedynczego wiersza kontrolki GridView.
Wprowadzenie
Kontrolka GridView oferuje wiele wbudowanych funkcji. Zawiera on wiele różnych pól do wyświetlania tekstu, obrazów, hiperlinków i przycisków. Obsługuje szablony do dalszego dostosowywania. Za pomocą kilku kliknięć myszy można ustawić kontrolkę GridView, w której można wybrać każdy wiersz za pomocą przycisku, lub włączyć edytowanie lub usuwanie możliwości. Pomimo wielu dostępnych funkcji, często będą istnieć sytuacje, w których należy dodać dodatkowe, nieobsługiwane funkcje. W tym samouczku i w kolejnych dwóch omówimy sposób ulepszania funkcji GridView w celu uwzględnienia dodatkowych funkcji.
Ten samouczek i następny z nich koncentrują się na ulepszaniu procesu wyboru wierszy. Zgodnie z analizą w elemecie Master/DetailView z kontrolką DetailsView z możliwością wyboru elementu Master GridView możemy dodać pole polecenia do kontrolki GridView, która zawiera przycisk Wybierz. Po kliknięciu zostanie zwrócona informacja zwrotna, a właściwość GridView zostanie SelectedIndex
zaktualizowana do indeksu wiersza, którego przycisk Wybierz został kliknięty. W samouczku Master/Detail Using a Selectable Master GridView with a Details DetailView (Szczegóły) pokazano, jak używać tej funkcji do wyświetlania szczegółów dla wybranego wiersza GridView.
Gdy przycisk Wybierz działa w wielu sytuacjach, może nie działać również dla innych osób. Zamiast używać przycisku, do zaznaczenia są często używane dwa inne elementy interfejsu użytkownika: przycisk radiowy i pole wyboru. Możemy rozszerzyć kontrolkę GridView, aby zamiast przycisku Wybierz każdy wiersz zawierał przycisk radiowy lub pole wyboru. W scenariuszach, w których użytkownik może wybrać tylko jeden z rekordów GridView, przycisk radiowy może być preferowany przez przycisk Wybierz. W sytuacjach, w których użytkownik może potencjalnie wybrać wiele rekordów, takich jak w aplikacji poczty e-mail opartej na sieci Web, gdzie użytkownik może wybrać wiele wiadomości, aby usunąć pole wyboru oferuje funkcje, które nie są dostępne w interfejsach użytkownika przycisku Wybierz lub przycisk radiowy.
W tym samouczku przedstawiono sposób dodawania kolumny przycisków radiowych do kontrolki GridView. Poniższy samouczek eksploruje pola wyboru przy użyciu pól wyboru.
Krok 1. Tworzenie ulepszania stron sieci Web GridView
Zanim zaczniemy ulepszać element GridView w celu uwzględnienia kolumny przycisków radiowych, najpierw poświęćmy chwilę, aby utworzyć strony ASP.NET w naszym projekcie witryny internetowej, które będą potrzebne w tym samouczku i w następnych dwóch. Zacznij od dodania nowego folderu o nazwie EnhancedGridView
. Następnie dodaj do tego folderu następujące strony ASP.NET, aby skojarzyć każdą stronę ze stroną wzorcową Site.master
:
Default.aspx
RadioButtonField.aspx
CheckBoxField.aspx
InsertThroughFooter.aspx
Rysunek 1. Dodawanie stron ASP.NET dla samouczków SqlDataSource-Related
Podobnie jak w przypadku innych folderów Default.aspx
, w EnhancedGridView
folderze zostaną wyświetlone samouczki w swojej sekcji. Pamiętaj, że kontrolka SectionLevelTutorialListing.ascx
użytkownika zapewnia tę funkcję. W związku z tym dodaj tę kontrolkę Default.aspx
użytkownika, przeciągając ją z Eksplorator rozwiązań do widoku projektu strony.
Rysunek 2. Dodawanie kontrolki SectionLevelTutorialListing.ascx
użytkownika do Default.aspx
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Na koniec dodaj te cztery strony jako wpisy do Web.sitemap
pliku. W szczególności dodaj następujące znaczniki po kontrolce SqlDataSource <siteMapNode>
:
<siteMapNode
title="Enhancing the GridView"
url="~/EnhancedGridView/Default.aspx"
description="Augment the user experience of the GridView control.">
<siteMapNode
url="~/EnhancedGridView/RadioButtonField.aspx"
title="Selection via a Radio Button Column"
description="Explore how to add a column of radio buttons in the GridView." />
<siteMapNode
url="~/EnhancedGridView/CheckBoxField.aspx"
title="Selection via a Checkbox Column"
description="Select multiple records in the GridView by using a column of
checkboxes." />
<siteMapNode
url="~/EnhancedGridView/InsertThroughFooter.aspx"
title="Add New Records through the Footer"
description="Learn how to allow users to add new records through the
GridView's footer." />
</siteMapNode>
Po zaktualizowaniu Web.sitemap
programu poświęć chwilę, aby wyświetlić witrynę internetową samouczków za pośrednictwem przeglądarki. Menu po lewej stronie zawiera teraz elementy do edycji, wstawiania i usuwania samouczków.
Rysunek 3. Mapa witryny zawiera teraz wpisy dotyczące ulepszania samouczków GridView
Krok 2. Wyświetlanie dostawców w siatceView
Na potrzeby tego samouczka skompilujmy widok GridView zawierający listę dostawców z USA, a każdy wiersz GridView udostępnia przycisk radiowy. Po wybraniu dostawcy za pośrednictwem przycisku radiowego użytkownik może wyświetlić produkty dostawcy, klikając przycisk. Chociaż to zadanie może brzmieć trywialne, istnieje wiele subtelności, które sprawiają, że jest to szczególnie trudne. Zanim zagłębimy się w te subtelności, najpierw pobierzmy usługę GridView z listą dostawców.
Zacznij od otwarcia RadioButtonField.aspx
strony w EnhancedGridView
folderze, przeciągając element GridView z przybornika do Projektant. Ustaw wartość GridView na ID
Suppliers
i, na podstawie tagu inteligentnego, wybierz opcję utworzenia nowego źródła danych. W szczególności utwórz obiekt ObjectDataSource o nazwie SuppliersDataSource
, który pobiera dane z SuppliersBLL
obiektu.
Rysunek 4. Tworzenie nowego obiektuDataSource nazwane SuppliersDataSource
(kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Rysunek 5. Konfigurowanie obiektu ObjectDataSource do używania SuppliersBLL
klasy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Ponieważ chcemy wyświetlić listę tylko tych dostawców w USA, wybierz GetSuppliersByCountry(country)
metodę z listy rozwijanej na karcie SELECT.
Rysunek 6. Konfigurowanie obiektu ObjectDataSource do używania SuppliersBLL
klasy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Na karcie UPDATE (Brak) wybierz opcję (Brak), a następnie kliknij przycisk Dalej.
Rysunek 7. Konfigurowanie obiektu ObjectDataSource do używania SuppliersBLL
klasy (kliknij, aby wyświetlić obraz pełnowymiarowy)
GetSuppliersByCountry(country)
Ponieważ metoda akceptuje parametr, kreator Konfiguruj źródło danych wyświetla monit o źródło tego parametru. Aby określić twardą wartość (USA, w tym przykładzie), pozostaw listę rozwijaną Źródło parametrów ustawioną na Wartość Brak i wprowadź wartość domyślną w polu tekstowym. Kliknij przycisk Zakończ, aby zakończyć kreatora.
Rysunek 8. Użyj usa jako wartości domyślnej parametru country
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Po ukończeniu pracy kreatora funkcja GridView będzie zawierać pole BoundField dla każdego pola danych dostawcy. Usuń wszystkie wartości , CompanyName
City
i Country
BoundFields i zmień nazwę CompanyName
właściwości BoundFields HeaderText
na Dostawca. Po wykonaniu tej czynności składni deklaratywnej GridView i ObjectDataSource powinny wyglądać podobnie do poniższej.
<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False"
DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource"
EnableViewState="False">
<Columns>
<asp:BoundField DataField="CompanyName" HeaderText="Supplier"
SortExpression="CompanyName" />
<asp:BoundField DataField="City" HeaderText="City"
SortExpression="City" />
<asp:BoundField DataField="Country" HeaderText="Country"
SortExpression="Country" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetSuppliersByCountry" TypeName="SuppliersBLL">
<SelectParameters>
<asp:Parameter DefaultValue="USA" Name="country" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
Na potrzeby tego samouczka pozwólmy użytkownikowi wyświetlić wybrane produkty dostawcy na tej samej stronie co lista dostawców lub na innej stronie. Aby to uwzględnić, dodaj do strony dwa kontrolki sieci Web przycisku. Ustawiłem ID
s z tych dwóch przycisków na ListProducts
i SendToProducts
, z pomysłem, że po ListProducts
kliknięciu po powrocie nastąpi, a wybrane produkty dostawcy zostaną wyświetlone na tej samej stronie, ale po SendToProducts
kliknięciu użytkownik zostanie whisked na innej stronie, która wyświetla listę produktów.
Rysunek 9 przedstawia kontrolkę Suppliers
GridView i dwie kontrolki sieci Web przycisków po wyświetleniu za pośrednictwem przeglądarki.
Rysunek 9. Dostawcy z USA Mają swoje nazwy, miasto i informacje o kraju wymienione (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 3. Dodawanie kolumny przycisków radiowych
W tym momencie obiekt Suppliers
GridView ma trzy pola Granic wyświetlające nazwę firmy, miasto i kraj każdego dostawcy w USA. Nadal brakuje jednak kolumny przycisków radiowych. Niestety, GridView nie zawiera wbudowanego elementu RadioButtonField, w przeciwnym razie możemy po prostu dodać to do siatki i zrobić. Zamiast tego możemy dodać element TemplateField i skonfigurować go ItemTemplate
tak, aby renderować przycisk radiowy, co powoduje kliknięcie przycisku radiowego dla każdego wiersza kontrolki GridView.
Początkowo możemy założyć, że żądany interfejs użytkownika można zaimplementować przez dodanie kontrolki Sieci Web RadioButton do ItemTemplate
pola szablonu. Chociaż spowoduje to rzeczywiście dodanie jednego przycisku radiowego do każdego wiersza elementu GridView, przyciski radiowe nie mogą być zgrupowane i dlatego nie wykluczają się wzajemnie. Oznacza to, że użytkownik końcowy może jednocześnie wybrać wiele przycisków radiowych z kontrolki GridView.
Mimo że użycie kontrolki Sieci Web TemplateField of RadioButton nie oferuje potrzebnych funkcji, zaimplementujmy to podejście, ponieważ warto sprawdzić, dlaczego wynikowe przyciski radiowe nie są pogrupowane. Zacznij od dodania pola TemplateField do elementu GridView dostawców, co czyni go najbardziej lewym polem. Następnie z tagu inteligentnego GridView kliknij link Edytuj szablony i przeciągnij kontrolkę Sieci Web RadioButton z przybornika do pola szablonów ItemTemplate
(zobacz Rysunek 10). Ustaw właściwość RadioButton ID
na RowSelector
i GroupName
właściwość na SuppliersGroup
.
Rysunek 10. Dodawanie kontrolki sieci Web RadioButton do elementu ItemTemplate
(kliknij, aby wyświetlić obraz pełnowymiarowy)
Po dodaniu tych dodatków za pośrednictwem Projektant znaczniki GridView powinny wyglądać podobnie do następujących:
<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False"
DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource"
EnableViewState="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:RadioButton ID="RowSelector" runat="server"
GroupName="SuppliersGroup" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="CompanyName" HeaderText="Supplier"
SortExpression="CompanyName" />
<asp:BoundField DataField="City" HeaderText="City"
SortExpression="City" />
<asp:BoundField DataField="Country" HeaderText="Country"
SortExpression="Country" />
</Columns>
</asp:GridView>
Właściwość RadioButton GroupName
jest używana do grupowania serii przycisków radiowych. Wszystkie kontrolki RadioButton o tej samej GroupName
wartości są traktowane jako pogrupowane. Jednocześnie można wybrać tylko jeden przycisk radiowy z grupy. Właściwość GroupName
określa wartość atrybutu renderowanego przycisku name
radiowego. Przeglądarka sprawdza atrybuty przycisków radiowych, aby określić grupy przycisków name
radiowych.
Za pomocą kontrolki RadioButton Web dodanej do ItemTemplate
elementu , odwiedź tę stronę za pośrednictwem przeglądarki i kliknij przyciski radiowe w wierszach siatki. Zwróć uwagę, że przyciski radiowe nie są pogrupowane, dzięki czemu można wybrać wszystkie wiersze, jak pokazano na rysunku 11.
Rysunek 11. Przyciski radiowe GridView nie są grupowane (kliknij, aby wyświetlić obraz pełnowymiarowy)
Powodem, dla którego przyciski radiowe nie są pogrupowane, jest to, że ich renderowane name
atrybuty są różne, mimo że mają to samo GroupName
ustawienie właściwości. Aby zobaczyć te różnice, wykonaj widok/źródło w przeglądarce i sprawdź znacznik przycisku radiowego:
<input id="ctl00_MainContent_Suppliers_ctl02_RowSelector"
name="ctl00$MainContent$Suppliers$ctl02$SuppliersGroup"
type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl03_RowSelector"
name="ctl00$MainContent$Suppliers$ctl03$SuppliersGroup"
type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl04_RowSelector"
name="ctl00$MainContent$Suppliers$ctl04$SuppliersGroup"
type="radio" value="RowSelector" />
<input id="ctl00_MainContent_Suppliers_ctl05_RowSelector"
name="ctl00$MainContent$Suppliers$ctl05$SuppliersGroup"
type="radio" value="RowSelector" />
Zwróć uwagę, że zarówno name
atrybuty, jak i id
nie są dokładnymi wartościami określonymi w okno Właściwości, ale są poprzedzane wieloma innymi ID
wartościami. Dodatkowe ID
wartości dodane do przodu renderowanego id
i name
atrybuty to ID
s przycisków radiowych nadrzędnych kontrole GridViewRow
sID
, GridView s , kontrolki Content s ID
ID
i formularzy ID
sieci Web . Są one ID
dodawane tak, aby każda renderowana kontrolka sieci Web w elemecie GridView ma unikatowe id
wartości i name
.
Każda renderowana kontrolka wymaga innej name
kontrolki i id
dlatego, że przeglądarka jednoznacznie identyfikuje każdą kontrolkę po stronie klienta i jak identyfikuje się z serwerem internetowym, jaka akcja lub zmiana wystąpiła po powrocie zwrotnej. Załóżmy na przykład, że chcemy uruchomić kod po stronie serwera za każdym razem, gdy stan sprawdzony elementu RadioButton został zmieniony. Możemy to osiągnąć, ustawiając właściwość RadioButton AutoPostBack
na True
i tworząc procedurę obsługi zdarzeń CheckChanged
dla zdarzenia. Jeśli jednak renderowane name
wartości i id
dla wszystkich przycisków radiowych były takie same, po powrocie nie mogliśmy określić, jaki konkretny przycisk RadioButton został kliknięty.
Krótko mówiąc, nie możemy utworzyć kolumny przycisków radiowych w kontrolce GridView przy użyciu kontrolki RadioButton Web. Zamiast tego musimy użyć raczej archaicznych technik, aby upewnić się, że odpowiednie znaczniki są wstrzykiwane do każdego wiersza GridView.
Uwaga
Podobnie jak kontrolka RadioButton Web, kontrolka HTML przycisku radiowego, po dodaniu do szablonu, będzie zawierać unikatowy name
atrybut, dzięki czemu przyciski radiowe w siatce niezgrupowane. Jeśli nie znasz kontrolek HTML, możesz zignorować tę notatkę, ponieważ rzadko używane są kontrolki HTML, szczególnie w ASP.NET 2.0. Jeśli jednak chcesz dowiedzieć się więcej, zobacz wpis w blogu K. Scott Allen Web Controls i kontrolki HTML.
Używanie kontrolki literału do wstrzykiwania znacznika przycisku radiowego
Aby poprawnie zgrupować wszystkie przyciski radiowe w elemecie GridView, musimy ręcznie wstrzyknąć znaczniki radiowe do elementu ItemTemplate
. Każdy przycisk radiowy wymaga tego samego name
atrybutu, ale powinien mieć unikatowy id
atrybut (jeśli chcemy uzyskać dostęp do przycisku radiowego za pośrednictwem skryptu po stronie klienta). Gdy użytkownik wybierze przycisk radiowy i opublikuje stronę z powrotem, przeglądarka wyśle z powrotem wartość wybranego atrybutu przycisku value
radiowego. W związku z tym każdy przycisk radiowy będzie potrzebował unikatowego value
atrybutu. Na koniec po powrocie musimy pamiętać o dodaniu atrybutu checked
do wybranego przycisku radiowego, w przeciwnym razie po wybraniu przez użytkownika zaznaczenia i wpisów przyciski radiowe powrócą do stanu domyślnego (wszystkie niezaznaczone).
Istnieją dwa podejścia, które można podjąć w celu wstrzyknięcia znaczników niskiego poziomu do szablonu. Jednym z nich jest wykonywanie kombinacji znaczników i wywołań do metod formatowania zdefiniowanych w klasie code-behind. Ta technika została po raz pierwszy omówiona w samouczku Using TemplateFields (Używanie pól szablonu w kontrolce GridView ). W naszym przypadku może to wyglądać mniej więcej tak:
<input type="radio" id='<%# GetUniqueRadioButtonID(...) %>'
name='SuppliersGroup' value='<%# GetRadioButtonValue(...) %>' ... />
GetUniqueRadioButton
W tym miejscu metody będą GetRadioButtonValue
zdefiniowane w klasie kodu, która zwróciła odpowiednie id
i value
atrybuty wartości dla każdego przycisku radiowego. Takie podejście dobrze sprawdza się w przypadku przypisywania id
atrybutów i value
, ale w przypadku konieczności określenia checked
wartości atrybutu, ponieważ składnia powiązania danych jest wykonywana tylko wtedy, gdy dane są najpierw powiązane z elementem GridView. W związku z tym jeśli element GridView ma włączony stan widoku, metody formatowania będą uruchamiane tylko wtedy, gdy strona zostanie załadowana po raz pierwszy (lub gdy element GridView jest jawnie odbicia do źródła danych), a zatem funkcja, która ustawia checked
atrybut, nie będzie wywoływana po powrocie zwrotnej. Jest to raczej subtelny problem i nieco poza zakresem tego artykułu, więc pozostawię to w tym miejscu. Zachęcam jednak do wypróbowania powyższego podejścia i pracy nad tym punktem, w którym utkniesz. Mimo że takie ćwiczenie nie przybliży Cię do wersji roboczej, pomoże ona lepiej zrozumieć element GridView i cykl życia łączenia danych.
Inne podejście do wstrzykiwania niestandardowych, niskiego poziomu znaczników w szablonie i podejście, którego będziemy używać w tym samouczku, polega na dodaniu kontrolki Literał do szablonu. Następnie w programie obsługi zdarzeń GridView RowCreated
lub RowDataBound
kontrolce literału można uzyskać dostęp programowy, a jej Text
właściwość ustawiona na znaczniki do emisji.
Zacznij od usunięcia elementu RadioButton z elementu TemplateField s ItemTemplate
, zastępując go kontrolką Literał. Ustaw kontrolkę Literał s ID
na RadioButtonMarkup
.
Rysunek 12. Dodawanie kontrolki literału do kontrolki ItemTemplate
(Kliknij, aby wyświetlić obraz pełnowymiarowy)
Następnie utwórz procedurę obsługi zdarzeń dla zdarzenia GridView.RowCreated
Zdarzenie RowCreated
jest uruchamiane raz dla każdego dodanego wiersza, niezależnie od tego, czy dane są ponownie przesyłane do elementu GridView. Oznacza to, że nawet w przypadku powrotu po ponownym załadowaniu danych ze stanu widoku zdarzenie nadal jest uruchamiane i jest to powód, RowCreated
dla którego używamy go zamiast RowDataBound
(co jest uruchamiane tylko wtedy, gdy dane są jawnie powiązane z kontrolką sieci Web danych).
W tej procedurze obsługi zdarzeń chcemy kontynuować tylko wtedy, gdy mamy do czynienia z wierszem danych. Dla każdego wiersza danych chcemy programowo odwołać RadioButtonMarkup
się do kontrolki Literał i ustawić jej Text
właściwość na znaczniki, aby emitować. Jak pokazano w poniższym kodzie, adiustacja emitowana tworzy przycisk radiowy, którego name
atrybut jest ustawiony na , którego id
atrybut jest ustawiony na SuppliersGroup
RowSelectorX
, gdzie X jest indeksem wiersza GridView i którego value
atrybut jest ustawiony na indeks wiersza GridView.
Protected Sub Suppliers_RowCreated(sender As Object, e As GridViewRowEventArgs) _
Handles Suppliers.RowCreated
If e.Row.RowType = DataControlRowType.DataRow Then
' Grab a reference to the Literal control
Dim output As Literal = _
CType(e.Row.FindControl("RadioButtonMarkup"), Literal)
' Output the markup except for the "checked" attribute
output.Text = String.Format( _
"<input type="radio" name="SuppliersGroup" " & _
"id="RowSelector{0}" value="{0}" />", e.Row.RowIndex)
End If
End Sub
Gdy zostanie wybrany wiersz GridView i nastąpi powrót, interesuje SupplierID
nas wybrany dostawca. W związku z tym można pomyśleć, że wartość każdego przycisku radiowego powinna być rzeczywista SupplierID
(a nie indeks wiersza GridView). Chociaż może to działać w pewnych okolicznościach, byłoby to zagrożenie bezpieczeństwa, aby ślepo zaakceptować i przetworzyć element SupplierID
. Nasz widok GridView zawiera na przykład listę tylko tych dostawców w USA. Jeśli SupplierID
jednak element jest przekazywany bezpośrednio z przycisku radiowego, co zatrzymać złośliwy użytkownik przed manipulowaniem SupplierID
wartością wysłaną z powrotem po powrocie? Używając indeksu wiersza jako value
elementu , a następnie pobierania SupplierID
po powrocie zwrotne z DataKeys
kolekcji, możemy upewnić się, że użytkownik używa tylko jednej z SupplierID
wartości skojarzonych z jednym z wierszy GridView.
Po dodaniu tego kodu procedury obsługi zdarzeń poświęć minutę, aby przetestować stronę w przeglądarce. Najpierw należy pamiętać, że jednocześnie można wybrać tylko jeden przycisk radiowy w siatce. Jednak po wybraniu przycisku radiowego i kliknięciu jednego z przycisków następuje powrót, a przyciski radiowe zostaną przywrócone do stanu początkowego (czyli po powrocie, wybrany przycisk radiowy nie jest już zaznaczony). Aby rozwiązać ten problem, musimy rozszerzyć procedurę RowCreated
obsługi zdarzeń tak, aby sprawdzała wybrany indeks przycisku radiowego wysłany z poświadczeń zwrotnych i dodaje checked="checked"
atrybut do emitowanego adiustacji dopasowań indeksu wierszy.
Po zakończeniu wycofywania przeglądarka wysyła z powrotem name
i value
wybranego przycisku radiowego. Wartość można pobrać programowo przy użyciu polecenia Request.Form("name")
. WłaściwośćRequest.Form
zawiera reprezentację NameValueCollection
zmiennych formularza. Zmienne formularza to nazwy i wartości pól formularza na stronie internetowej i są wysyłane z powrotem przez przeglądarkę internetową za każdym razem, gdy następuje powrót po powrocie. Ponieważ renderowany name
atrybut przycisków radiowych w elemecie GridView to SuppliersGroup
, gdy strona internetowa zostanie wysłana z powrotem, przeglądarka zostanie odesłana SuppliersGroup=valueOfSelectedRadioButton
do serwera internetowego (wraz z innymi polami formularza). Te informacje można następnie uzyskać z Request.Form
właściwości przy użyciu polecenia : Request.Form("SuppliersGroup")
.
Ponieważ musimy określić wybrany indeks przycisku radiowego nie tylko w RowCreated
procedurze obsługi zdarzeń, ale także w Click
programach obsługi zdarzeń dla kontrolek Sieci Web przycisków, dodajmy SuppliersSelectedIndex
właściwość do klasy za pomocą kodu, która zwraca -1
, jeśli nie wybrano przycisku radiowego i wybrany indeks, jeśli wybrano jeden z przycisków radiowych.
Private ReadOnly Property SuppliersSelectedIndex() As Integer
Get
If String.IsNullOrEmpty(Request.Form("SuppliersGroup")) Then
Return -1
Else
Return Convert.ToInt32(Request.Form("SuppliersGroup"))
End If
End Get
End Property
Po dodaniu tej właściwości wiemy, aby dodać znaczniki checked="checked"
w procedurze RowCreated
obsługi zdarzeń, gdy SuppliersSelectedIndex
jest równa e.Row.RowIndex
. Zaktualizuj procedurę obsługi zdarzeń, aby uwzględnić następującą logikę:
Protected Sub Suppliers_RowCreated(sender As Object, e As GridViewRowEventArgs) _
Handles Suppliers.RowCreated
If e.Row.RowType = DataControlRowType.DataRow Then
' Grab a reference to the Literal control
Dim output As Literal = _
CType(e.Row.FindControl("RadioButtonMarkup"), Literal)
' Output the markup except for the "checked" attribute
output.Text = String.Format( _
"<input type="radio" name="SuppliersGroup" " & _
"id="RowSelector{0}" value="{0}"", e.Row.RowIndex)
' See if we need to add the "checked" attribute
If SuppliersSelectedIndex = e.Row.RowIndex Then
output.Text &= " checked="checked""
End If
' Add the closing tag
output.Text &= " />"
End If
End Sub
Po tej zmianie wybrany przycisk radiowy pozostaje zaznaczony po powłoce. Teraz, gdy mamy możliwość określenia, jaki przycisk radiowy jest zaznaczony, możemy zmienić zachowanie tak, aby po pierwszym odwiedzeniu strony pierwszy przycisk radiowy wiersza GridView został wybrany (zamiast domyślnie nie mieć wybranych przycisków radiowych, co jest bieżącym zachowaniem). Aby domyślnie wybrać pierwszy przycisk radiowy, po prostu zmień instrukcję If SuppliersSelectedIndex = e.Row.RowIndex Then
na następującą: If SuppliersSelectedIndex = e.Row.RowIndex OrElse (Not Page.IsPostBack AndAlso e.Row.RowIndex = 0) Then
.
W tym momencie dodaliśmy kolumnę pogrupowanych przycisków radiowych do kontrolki GridView, która umożliwia wybranie pojedynczego wiersza kontrolki GridView i zapamiętanie ich po powrocie. Następne kroki to wyświetlenie produktów dostarczonych przez wybranego dostawcę. W kroku 4 zobaczymy, jak przekierować użytkownika do innej strony, wysyłając dane wzdłuż wybranego SupplierID
elementu . W kroku 5 zobaczymy, jak wyświetlić wybrane produkty dostawcy w elemecie GridView na tej samej stronie.
Uwaga
Zamiast używać pola TemplateField (fokus tego długiego kroku 3), możemy utworzyć klasę niestandardową DataControlField
, która renderuje odpowiedni interfejs użytkownika i funkcjonalność. KlasaDataControlField
jest klasą bazową, z której pochodzą pola BoundField, CheckBoxField, TemplateField i inne wbudowane pola GridView i DetailsView. Utworzenie klasy niestandardowej DataControlField
oznaczałoby, że można dodać kolumnę przycisków radiowych tylko przy użyciu składni deklaratywnej, a także znacznie ułatwić replikowanie funkcji na innych stronach internetowych i innych aplikacjach internetowych.
Jeśli kiedykolwiek utworzono niestandardowe, skompilowane kontrolki w ASP.NET, jednak wiesz, że wymaga to dość dużo pracy w nogach i niesie ze sobą wiele subtelności i przypadków krawędzi, które muszą być starannie obsługiwane. W związku z tym będziemy wdrażać kolumnę przycisków radiowych jako klasę niestandardową DataControlField
na razie i trzymać się opcji TemplateField. Być może będziemy mieli szansę zapoznać się z tworzeniem, używaniem i wdrażaniem klas niestandardowych DataControlField
w przyszłym samouczku.
Krok 4. Wyświetlanie wybranych produktów dostawcy na oddzielnej stronie
Gdy użytkownik wybrał wiersz GridView, musimy wyświetlić wybrane produkty dostawcy. W niektórych okolicznościach możemy chcieć wyświetlić te produkty na osobnej stronie, a inne wolisz to zrobić na tej samej stronie. Najpierw sprawdźmy, jak wyświetlać produkty na osobnej stronie; W kroku 5 przyjrzymy się dodaniu elementu GridView do RadioButtonField.aspx
wyświetlania wybranych produktów dostawcy.
Obecnie na stronie ListProducts
znajdują się dwie kontrolki sieci Web Przycisk i SendToProducts
. Po kliknięciu SendToProducts
przycisku chcemy wysłać użytkownika do ~/Filtering/ProductsForSupplierDetails.aspx
. Ta strona została utworzona w samouczku Filtrowanie wzorca/szczegółów między dwiema stronami i wyświetla produkty dostawcy, którego SupplierID
dane są przekazywane za pośrednictwem pola tworzenia zapytań o nazwie SupplierID
.
Aby zapewnić tę funkcję, utwórz procedurę obsługi zdarzeń dla SendToProducts
zdarzenia Przycisk Click
. W kroku 3 dodaliśmy SuppliersSelectedIndex
właściwość, która zwraca indeks wiersza, którego przycisk radiowy jest zaznaczony. Odpowiednie dane SupplierID
można pobrać z kolekcji GridView, DataKeys
a użytkownik może następnie zostać wysłany do ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID
programu przy użyciu polecenia Response.Redirect("url")
.
Protected Sub SendToProducts_Click(sender As Object, e As EventArgs) _
Handles SendToProducts.Click
' Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
Dim supplierID As Integer = _
Convert.ToInt32(Suppliers.DataKeys(SuppliersSelectedIndex).Value)
Response.Redirect( _
"~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=" & _
supplierID)
End Sub
Ten kod działa cudownie, o ile jeden z przycisków radiowych jest wybierany z kontrolki GridView. Jeśli początkowo element GridView nie ma zaznaczonych przycisków radiowych, a użytkownik kliknie SendToProducts
przycisk , będzie -1
to , SuppliersSelectedIndex
co spowoduje zgłoszenie wyjątku, ponieważ -1
jest poza zakresem indeksu DataKeys
kolekcji. Nie jest to jednak problem, jeśli zdecydujesz się zaktualizować RowCreated
procedurę obsługi zdarzeń zgodnie z opisem w kroku 3, aby początkowo wybrać pierwszy przycisk radiowy w siatce.
Aby uwzględnić SuppliersSelectedIndex
wartość elementu -1
, dodaj kontrolkę Etykieta sieci Web do strony powyżej kontrolki GridView. ID
ChooseSupplierMsg
Ustaw właściwość na , jej CssClass
właściwość na Warning
, jej EnableViewState
właściwości False
i Visible
na , a jej Text
właściwość na Wybierz dostawcę z siatki. Klasa Warning
CSS wyświetla tekst w czerwonej, kursywie, pogrubionej, dużej czcionki i jest definiowany w pliku Styles.css
. Ustawiając EnableViewState
właściwości i Visible
na False
, etykieta nie jest renderowana z wyjątkiem tylko tych poświadczeń, w których właściwość kontrolki Visible
jest programowo ustawiona na True
.
Rysunek 13. Dodawanie kontrolki sieci Web etykiety nad kontrolką GridView (kliknij, aby wyświetlić obraz pełnowymiarowy)
Następnie rozszerz procedurę Click
obsługi zdarzeń, aby wyświetlić etykietę ChooseSupplierMsg
, jeśli SuppliersSelectedIndex
jest mniejsza niż zero, i przekieruj użytkownika do ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID
innego.
Protected Sub SendToProducts_Click(sender As Object, e As EventArgs) _
Handles SendToProducts.Click
' make sure one of the radio buttons has been selected
If SuppliersSelectedIndex < 0 Then
ChooseSupplierMsg.Visible = True
Else
' Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
Dim supplierID As Integer = _
Convert.ToInt32(Suppliers.DataKeys(SuppliersSelectedIndex).Value)
Response.Redirect( _
"~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=" & _
supplierID)
End If
End Sub
Odwiedź stronę w przeglądarce i kliknij SendToProducts
przycisk przed wybraniem dostawcy z widoku GridView. Jak pokazano na rysunku 14, zostanie wyświetlona etykieta ChooseSupplierMsg
. Następnie wybierz dostawcę i kliknij SendToProducts
przycisk. Spowoduje to whisk do strony zawierającej listę produktów dostarczonych przez wybranego dostawcę. Rysunek 15 przedstawia stronę po wybraniu ProductsForSupplierDetails.aspx
dostawcy Bigfoot Breweries.
Rysunek 14. Etykieta jest wyświetlana ChooseSupplierMsg
, jeśli nie wybrano dostawcy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Rysunek 15. Wyświetlane ProductsForSupplierDetails.aspx
są produkty wybranego dostawcy (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Krok 5. Wyświetlanie wybranych produktów dostawców na tej samej stronie
W kroku 4 pokazano, jak wysłać użytkownika do innej strony internetowej w celu wyświetlenia wybranych produktów dostawców. Alternatywnie wybrane produkty dostawcy mogą być wyświetlane na tej samej stronie. Aby to zilustrować, dodamy kolejny element GridView, aby wyświetlić RadioButtonField.aspx
wybrane produkty dostawców.
Ponieważ chcemy, aby ten element GridView produktów był wyświetlany tylko po wybraniu dostawcy, dodaj kontrolkę Panel sieci Web pod Suppliers
kontrolką GridView, ustawiając jej ID
właściwość na ProductsBySupplierPanel
i jej Visible
właściwość na False
. W panelu dodaj tekst Products for the Selected Supplier (Produkty wybranego dostawcy), a następnie gridView o nazwie ProductsBySupplier
. W tagu inteligentnym GridView wybierz powiązanie go z nowym obiektem ObjectDataSource o nazwie ProductsBySupplierDataSource
.
Rysunek 16. Powiązanie kontrolki ProductsBySupplier
GridView z nowym obiektem ObjectDataSource (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Następnie skonfiguruj obiekt ObjectDataSource do używania ProductsBLL
klasy . Ponieważ chcemy tylko pobrać te produkty dostarczone przez wybranego dostawcę, określ, że obiekt ObjectDataSource powinien wywołać metodę GetProductsBySupplierID(supplierID)
w celu pobrania danych. Wybierz pozycję (Brak) z list rozwijanych na kartach UPDATE, INSERT i DELETE.
Rysunek 17. Konfigurowanie obiektu ObjectDataSource do użycia GetProductsBySupplierID(supplierID)
metody (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Rysunek 18. Ustawianie Drop-Down Listy na wartość (Brak) na kartach UPDATE, INSERT i DELETE (Kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po skonfigurowaniu kart SELECT, UPDATE, INSERT i DELETE kliknij przycisk Dalej. GetProductsBySupplierID(supplierID)
Ponieważ metoda oczekuje parametru wejściowego, kreator Tworzenia źródła danych monituje nas o określenie źródła dla wartości parametru.
W tym miejscu mamy kilka opcji określania źródła wartości parametru. Możemy użyć domyślnego obiektu Parameter i programowo przypisać wartość SuppliersSelectedIndex
właściwości do właściwości Parameter DefaultValue
w programie obsługi zdarzeń ObjectDataSource Selecting
. Wróć do samouczka Programmatically Setting the ObjectDataSource's Parameter Values (Programowe ustawianie wartości parametrów obiektu ObjectDataSource ), aby odświeżyć moduł do programowego przypisywania wartości do parametrów obiektuDataSource.
Alternatywnie możemy użyć kontrolki ControlParameter i odwołać się do Suppliers
właściwości GridView SelectedValue
(zobacz Rysunek 19). Właściwość GridView SelectedValue
zwraca DataKey
wartość odpowiadającą SelectedIndex
właściwości . Aby ta opcja działała, musimy programowo ustawić właściwość GridView na SelectedIndex
wybrany wiersz po kliknięciu ListProducts
przycisku. W ramach dodatkowej SelectedIndex
korzyści ustawienie elementu spowoduje, że wybrany rekord zostanie włączony SelectedRowStyle
zgodnie z DataWebControls
definicją w motywie (żółtym tle).
Rysunek 19. Użyj kontrolkiParameter, aby określić element GridView s SelectedValue jako źródło parametrów (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
Po ukończeniu pracy kreatora program Visual Studio automatycznie doda pola dla pól danych produktu. Usuń wszystkie elementy ProductName
, CategoryName
i UnitPrice
BoundFields, a następnie zmień HeaderText
właściwości na Product, Category i Price. Skonfiguruj pole BoundField tak UnitPrice
, aby jego wartość została sformatowana jako waluta. Po wprowadzeniu tych zmian znaczniki deklaratywne panelowe, GridView i ObjectDataSource powinny wyglądać następująco:
<asp:Panel runat="server" ID="ProductsBySupplierPanel" Visible="False">
<h3>
Products for the Selected Supplier</h3>
<p>
<asp:GridView ID="ProductsBySupplier" runat="server"
AutoGenerateColumns="False" DataKeyNames="ProductID"
DataSourceID="ProductsBySupplierDataSource" 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="ProductsBySupplierDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProductsBySupplierID" TypeName="ProductsBLL">
<SelectParameters>
<asp:ControlParameter ControlID="Suppliers" Name="supplierID"
PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
</p>
</asp:Panel>
Aby ukończyć to ćwiczenie, należy ustawić właściwość GridView SelectedIndex
na SelectedSuppliersIndex
właściwość i ProductsBySupplierPanel
właściwość Visible
Panel na True
po kliknięciu ListProducts
przycisku. W tym celu utwórz procedurę obsługi zdarzeń dla ListProducts
zdarzenia kontrolki Click
Sieci Web przycisku i dodaj następujący kod:
Protected Sub ListProducts_Click(sender As Object, e As EventArgs) _
Handles ListProducts.Click
' make sure one of the radio buttons has been selected
If SuppliersSelectedIndex < 0 Then
ChooseSupplierMsg.Visible = True
ProductsBySupplierPanel.Visible = False
Else
' Set the GridView's SelectedIndex
Suppliers.SelectedIndex = SuppliersSelectedIndex
' Show the ProductsBySupplierPanel panel
ProductsBySupplierPanel.Visible = True
End If
End Sub
Jeśli dostawca nie został wybrany z kontrolki GridView, ChooseSupplierMsg
zostanie wyświetlona etykieta i ProductsBySupplierPanel
panel ukryty. W przeciwnym razie, jeśli wybrano dostawcę, ProductsBySupplierPanel
zostanie wyświetlona wartość , a właściwość GridView zostanie zaktualizowana SelectedIndex
.
Rysunek 20 przedstawia wyniki po wybraniu dostawcy Bigfoot Breweries i kliknięciu przycisku Pokaż produkty na stronie.
Rysunek 20. Produkty dostarczone przez Bigfoot Breweries są wyświetlane na tej samej stronie (kliknij, aby wyświetlić obraz pełnowymiarowy)
Podsumowanie
Zgodnie z opisem w samouczku Master/Detail Using a Selectable Master GridView with a Details DetailView (Szczegóły) rekordy można wybrać z obiektu GridView przy użyciu kontrolki CommandField, której ShowSelectButton
właściwość jest ustawiona na True
wartość . Jednak pole CommandField wyświetla przyciski jako zwykłe przyciski, linki lub obrazy. Alternatywny interfejs użytkownika wyboru wiersza polega na podaniu przycisku radiowego lub pola wyboru w każdym wierszu Kontrolka GridView. W tym samouczku sprawdziliśmy, jak dodać kolumnę przycisków radiowych.
Niestety dodanie kolumny przycisków radiowych nie jest tak proste, jak można się spodziewać. Nie ma wbudowanego elementu RadioButtonField, które można dodać po kliknięciu przycisku, a użycie kontrolki Sieci Web RadioButton w elemecie TemplateField wprowadza własny zestaw problemów. W końcu, aby zapewnić taki interfejs, musimy utworzyć niestandardową DataControlField
klasę lub uciekać się do wstrzykiwania odpowiedniego kodu HTML do pola templatefield podczas RowCreated
zdarzenia.
Po zapoznaniu się z dodawaniem kolumny przycisków radiowych zwróćmy uwagę na dodanie kolumny pól wyboru. Przy użyciu kolumny pól wyboru użytkownik może wybrać co najmniej jeden wiersz GridView, a następnie wykonać operację na wszystkich zaznaczonych wierszach (na przykład wybranie zestawu wiadomości e-mail z internetowego klienta poczty e-mail, a następnie wybranie usunięcia wszystkich wybranych wiadomości e-mail). W następnym samouczku zobaczymy, jak dodać taką kolumnę.
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 do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.
Specjalne podziękowania
Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Głównym recenzentem tego samouczka był David Suru. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresemmitchell@4GuysFromRolla.com .