Dodawanie kolumny przycisków radiowych do kontrolki GridView (C#)
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
elementu i name
atrybuty to ID
s przycisków radiowych nadrzędnych kontrole GridViewRow
s ID
, GridView s ID
, kontrolki Content s ID
i formularzy ID
sieci Web. Są one ID
dodawane tak, aby każda renderowana kontrolka sieci Web w kontrolce GridView zawiera unikatowe id
wartości i name
.
Każda renderowana kontrolka wymaga innego name
działania i id
ponieważ jest to sposób, w jaki przeglądarka jednoznacznie identyfikuje każdą kontrolkę po stronie klienta i jak identyfikuje serwer internetowy, jaka akcja lub zmiana wystąpiła po powłoce. Załóżmy na przykład, że chcemy uruchomić kod po stronie serwera za każdym razem, gdy stan sprawdzania 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ń dla CheckChanged
zdarzenia. Jeśli jednak renderowane name
wartości i id
dla wszystkich przycisków radiowych były takie same, po ogłaszaniu zwrotnym nie mogliśmy określić, jakie konkretne przyciski RadioButton zostały kliknięte.
Krótko mówiąc, nie możemy utworzyć kolumny przycisków radiowych w kontrolce GridView przy użyciu kontrolki RadioButton Web. Zamiast tego należy 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ę uwagę, ponieważ kontrolki HTML są rzadko używane, szczególnie w ASP.NET 2.0. Jeśli jednak chcesz dowiedzieć się więcej, zobacz wpis w blogu K. Scott AllenWeb Controls i kontrolki HTML.
Używanie kontrolki literału do wstrzykiwania znaczników radiowych
Aby poprawnie zgrupować wszystkie przyciski radiowe w elementy 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 (w przypadku, gdy 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 value
przycisku 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 gdy użytkownik dokona wyboru i opublikuje go z powrotem, przyciski radiowe powrócą do stanu domyślnego (wszystkie niezaznaczone).
Istnieją dwa podejścia, które można zastosować w celu wprowadzenia znaczników niskiego poziomu do szablonu. Jednym z nich jest wykonywanie kombinacji znaczników i wywołań do metod formatowania zdefiniowanych w klasie za kodem. Ta technika została po raz pierwszy omówiona w samouczku Using TemplateFields (Używanie pól szablonów 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 i GetRadioButtonValue
będą zdefiniowane w klasie kodu, która zwróciła odpowiednie id
wartości atrybutów i value
dla każdego przycisku radiowego. Takie podejście dobrze sprawdza się w przypadku przypisywania id
atrybutów i value
, ale nie ma potrzeby określania wartości atrybutu checked
, ponieważ składnia powiązania danych jest wykonywana tylko wtedy, gdy dane są najpierw powiązane z obiektem GridView. W związku z tym jeśli kontrolka GridView ma włączony stan wyświetlania, metody formatowania będą uruchamiane tylko wtedy, gdy strona zostanie załadowana po raz pierwszy (lub gdy obiekt GridView jawnie odbicia do źródła danych), a zatem funkcja, która ustawia checked
atrybut, nie zostanie wywołana przy ogłaszaniu zwrotnym. Jest to dość subtelny problem i nieco poza zakresem tego artykułu, więc zostawię go na tym. Zachęcam jednak do wypróbowania powyższego podejścia i pracy z nim do punktu, w którym utkniesz. Chociaż takie ćwiczenie nie przybliży Cię do działającej wersji, pomoże ci lepiej zrozumieć element GridView i cykl życia powiązania danych.
Innym podejściem do wstrzykiwania niestandardowych, niskiego poziomu znaczników w szablonie i podejściem, którego użyjemy w tym samouczku, jest dodanie kontrolki Literał do szablonu. Następnie w programie obsługi zdarzeń gridView RowCreated
RowDataBound
można uzyskać dostęp programowy do kontrolki Literał, a jej Text
właściwość ustawiona na znaczniki do emitowania.
Zacznij od usunięcia elementu RadioButton z elementu TemplateField, ItemTemplate
zastępując go kontrolką Literał. Ustaw kontrolkę Literał na ID
RadioButtonMarkup
wartość .
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ą odbicia do kontrolki GridView. Oznacza to, że nawet w przypadku ogłaszania zwrotnego, gdy dane są ponownie ładowane ze stanu widoku, zdarzenie nadal jest uruchamiane i jest to powód, dla którego używamy go zamiast RowDataBound
(co jest uruchamiane tylko wtedy, RowCreated
gdy dane są jawnie powiązane z kontrolką internetową 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ływać się RadioButtonMarkup
do kontrolki Literał i ustawić jej Text
właściwość na adiustację, aby emitować. Jak pokazano w poniższym kodzie, adiustacja emitowana tworzy przycisk radiowy, którego name
atrybut jest ustawiony na SuppliersGroup
, którego id
atrybut jest ustawiony na RowSelectorX
, gdzie X jest indeksem wiersza GridView i którego value
atrybut jest ustawiony na indeks wiersza GridView.
protected void Suppliers_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Grab a reference to the Literal control
Literal output = (Literal)e.Row.FindControl("RadioButtonMarkup");
// 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);
}
}
Po wybraniu wiersza GridView i wystąpieniu ogłaszania zwrotnego jesteśmy zainteresowani SupplierID
wybranym dostawcą. 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, zagrożeniem dla bezpieczeństwa byłoby ślepe akceptowanie i przetwarzanie elementu SupplierID
. Nasz element GridView, na przykład, zawiera listę tylko tych dostawców w STANACH Zjednoczonych. 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 wysłaniu zwrotnym? Używając indeksu value
wierszy jako elementu , a następnie pobierania SupplierID
polecenia ogłaszania zwrotnego z DataKeys
kolekcji, możemy upewnić się, że użytkownik używa tylko jednej z SupplierID
wartości skojarzonych z jednym z wierszy kontrolki GridView.
Po dodaniu tego kodu procedury obsługi zdarzeń poświęć chwilę na przetestowanie strony 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 ogłaszanie zwrotne, a przyciski radiowe zostaną przywrócone do stanu początkowego (to znaczy po wyświetleniu powrotu wybrany przycisk radiowy nie jest już zaznaczony). Aby rozwiązać ten problem, musimy rozszerzyć RowCreated
program obsługi zdarzeń tak, aby sprawdzał wybrany indeks przycisku radiowego wysłany z ogłaszania zwrotnego i dodaje checked="checked"
atrybut do emitowanego znaczników indeksu wierszy.
Po wystąpieniu ogłaszania zwrotnego 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 ogłaszanie zwrotne. Ponieważ renderowany name
atrybut przycisków radiowych w siatceView to SuppliersGroup
, gdy strona internetowa zostanie opublikowana z powrotem, przeglądarka wyśle SuppliersGroup=valueOfSelectedRadioButton
z powrotem do serwera internetowego (wraz z innymi polami formularza). Dostęp do tych informacji można uzyskać z Request.Form
właściwości przy użyciu: 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 przycisku, dodajmy SuppliersSelectedIndex
właściwość do klasy kodu, która zwraca -1
wartość, jeśli nie wybrano przycisku radiowego, a wybrany indeks, jeśli wybrano jeden z przycisków radiowych.
private int SuppliersSelectedIndex
{
get
{
if (string.IsNullOrEmpty(Request.Form["SuppliersGroup"]))
return -1;
else
return Convert.ToInt32(Request.Form["SuppliersGroup"]);
}
}
Po dodaniu tej właściwości wiemy, że dodamy checked="checked"
znaczniki w procedurze RowCreated
obsługi zdarzeń, gdy SuppliersSelectedIndex
jest e.Row.RowIndex
równa . Zaktualizuj program obsługi zdarzeń, aby uwzględnić następującą logikę:
protected void Suppliers_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Grab a reference to the Literal control
Literal output = (Literal)e.Row.FindControl("RadioButtonMarkup");
// 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)
output.Text += @" checked="checked"";
// Add the closing tag
output.Text += " />";
}
}
Po wprowadzeniu tej zmiany wybrany przycisk radiowy pozostaje zaznaczony po zakończeniu ogłaszania zwrotnego. Teraz, gdy mamy możliwość określenia wybranego przycisku radiowego, możemy zmienić zachowanie tak, aby po pierwszym odwiedzeniu strony zaznaczono pierwszy przycisk radiowy wiersza Kontrolka GridView (zamiast domyślnie nie wybierać żadnych przycisków radiowych, co jest bieżącym zachowaniem). Aby domyślnie wybrać pierwszy przycisk radiowy, po prostu zmień instrukcję if (SuppliersSelectedIndex == e.Row.RowIndex)
na następującą: if (SuppliersSelectedIndex == e.Row.RowIndex || (!Page.IsPostBack && e.Row.RowIndex == 0))
.
W tym momencie dodaliśmy kolumnę pogrupowanych przycisków radiowych do kontrolki GridView, która umożliwia wybranie pojedynczego wiersza kontrolki GridView i zapamiętowanie ich w ramach ogłaszania zwrotnego. Następnym krokiem jest wyświetlenie produktów dostarczonych przez wybranego dostawcę. W kroku 4 zobaczymy, jak przekierować użytkownika do innej strony, wysyłając do wybranej strony SupplierID
. W kroku 5 zobaczymy, jak wyświetlić wybrane produkty dostawcy w elementy GridView na tej samej stronie.
Uwaga
Zamiast korzystać z pola TemplateField (fokus tego długiego kroku 3), możemy utworzyć klasę niestandardową DataControlField
, która renderuje odpowiedni interfejs użytkownika i funkcje. KlasaDataControlField
jest klasą bazową, z której pochodzą pola BoundField, CheckBoxField, TemplateField i inne wbudowane pola GridView i DetailsView. Utworzenie niestandardowej DataControlField
klasy 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 sporo legwork i prowadzi z nim wiele subtelności i przypadków krawędzi, które muszą być starannie obsługiwane. W związku z tym wdrożymy teraz kolumnę przycisków radiowych jako klasę niestandardową DataControlField
i będziemy trzymać się opcji TemplateField. Być może będziemy mieli okazję zapoznać się z tworzeniem, używaniem i wdrażaniem klas niestandardowych DataControlField
w przyszłym samouczku.
Krok 4. Wyświetlanie wybranych produktów dostawców na oddzielnej stronie
Gdy użytkownik wybrał wiersz GridView, musimy wyświetlić wybrane produkty dostawców. W niektórych okolicznościach możemy chcieć wyświetlić te produkty na osobnej stronie. W innych przypadkach możemy chcieć to zrobić na tej samej stronie. Najpierw sprawdźmy, jak wyświetlać produkty na osobnej stronie; W kroku 5 przyjrzymy się dodaniu kontrolki GridView w RadioButtonField.aspx
celu wyświetlenia wybranych produktów dostawców.
Obecnie na stronie ListProducts
znajdują się dwie kontrolki sieci Web przycisków 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 na dwóch stronach i wyświetla produkty dla dostawcy, którego SupplierID
dane są przekazywane przez pole querystring o nazwie SupplierID
.
Aby zapewnić tę funkcję, utwórz procedurę obsługi zdarzeń dla SendToProducts
zdarzenia Przycisku Click
. W kroku 3 dodaliśmy SuppliersSelectedIndex
właściwość , która zwraca indeks wiersza, którego przycisk radiowy jest zaznaczony. Odpowiednie SupplierID
dane można pobrać z kolekcji GridView DataKeys
, a użytkownik może następnie zostać wysłany przy ~/Filtering/ProductsForSupplierDetails.aspx?SupplierID=SupplierID
użyciu polecenia Response.Redirect("url")
.
protected void SendToProducts_Click(object sender, EventArgs e)
{
// Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
int supplierID =
Convert.ToInt32(Suppliers.DataKeys[SuppliersSelectedIndex].Value);
Response.Redirect(
"~/Filtering/ProductsForSupplierDetails.aspx?SupplierID="
+ supplierID);
}
}
Ten kod działa cudownie, o ile jeden z przycisków radiowych jest wybierany z kontrolki GridView. Jeśli początkowo kontrolka 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, tak aby pierwszy przycisk radiowy w siatceView początkowo został wybrany.
Aby uwzględnić wartość -1
, dodaj kontrolkę SuppliersSelectedIndex
Sieć Web etykiet do strony powyżej kontrolki GridView. Ustaw jej ID
właściwość na ChooseSupplierMsg
, jej CssClass
właściwość na Warning
, jej EnableViewState
właściwości i Visible
na false
, a jej Text
właściwość na Proszę wybrać dostawcę z siatki. Klasa Warning
CSS wyświetla tekst w kolorze czerwonym, kursywą, pogrubioną, dużą czcionką i jest zdefiniowany w pliku Styles.css
. EnableViewState
Ustawiając właściwości false
i Visible
na wartość , etykieta nie jest renderowana z wyjątkiem tylko tych ogłaszania zwrotnego, w których właściwość kontrolki Visible
jest programowo ustawiona na true
wartość .
Rysunek 13. Dodawanie kontrolki sieci Web etykiety nad kontrolką GridView (kliknij, aby wyświetlić obraz o pełnym rozmiarze)
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 void SendToProducts_Click(object sender, EventArgs e)
{
// make sure one of the radio buttons has been selected
if (SuppliersSelectedIndex < 0)
ChooseSupplierMsg.Visible = true;
else
{
// Send the user to ~/Filtering/ProductsForSupplierDetails.aspx
int supplierID =
Convert.ToInt32(Suppliers.DataKeys[SuppliersSelectedIndex].Value);
Response.Redirect(
"~/Filtering/ProductsForSupplierDetails.aspx?SupplierID="
+ supplierID);
}
}
Odwiedź stronę w przeglądarce i kliknij SendToProducts
przycisk przed wybraniem dostawcy z kontrolki GridView. Jak pokazano na rysunku 14, zostanie wyświetlona etykieta ChooseSupplierMsg
. Następnie wybierz dostawcę i kliknij SendToProducts
przycisk . Spowoduje to wąsanie na stronę zawierającą 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 w pełnym rozmiarze)
Rysunek 15. Wyświetlane ProductsForSupplierDetails.aspx
są wybrane produkty dostawcy (kliknij, aby wyświetlić obraz pełnowymiarowy)
Krok 5. Wyświetlanie wybranych produktów dostawcy na tej samej stronie
W kroku 4 pokazano, jak wysłać użytkownika do innej strony internetowej, aby wyświetlić wybrane produkty dostawcy. Alternatywnie wybrane produkty dostawcy mogą być wyświetlane na tej samej stronie. Aby to zilustrować, dodamy kolejny element GridView, aby RadioButtonField.aspx
wyświetlić wybrane produkty dostawcy.
Ponieważ chcemy, aby ten element GridView produktów był wyświetlany tylko po wybraniu Suppliers
dostawcy, dodaj kontrolkę Sieć Web Panelu pod kontrolką GridView, ustawiając jej ID
właściwość false
na ProductsBySupplierPanel
.Visible
W panelu dodaj tekst Products for the Selected Supplier (Produkty wybranego dostawcy), a następnie pozycję GridView o nazwie ProductsBySupplier
. Z tagu inteligentnego GridView wybierz powiązanie go z nowym obiektem ObjectDataSource o nazwie ProductsBySupplierDataSource
.
Rysunek 16. Powiązanie elementu ProductsBySupplier
GridView z nowym obiektemDataSource (kliknij, aby wyświetlić obraz pełnowymiarowy)
Następnie skonfiguruj obiekt ObjectDataSource do używania ProductsBLL
klasy . Ponieważ chcemy pobrać tylko 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 pełnowymiarowy)
Rysunek 18. Ustaw Drop-Down Listy na (Brak) na kartach UPDATE, INSERT i DELETE (Kliknij, aby wyświetlić obraz pełnowymiarowy)
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 wartości parametru.
W tym miejscu mamy kilka opcji określania źródła wartości parametru. Można użyć domyślnego obiektu Parametr i programowo przypisać wartość SuppliersSelectedIndex
właściwości do właściwości Parameter DefaultValue
w programie obsługi zdarzeń ObjectDataSource Selecting
. Zapoznaj się z samouczkiem Programowe ustawianie wartości parametrów obiektu ObjectDataSource w celu programowego przypisywania wartości do parametrów objectDataSource.
Alternatywnie możemy użyć kontrolkiParameter i odwołać się do Suppliers
właściwości GridView SelectedValue
(zobacz Rysunek 19). Właściwość GridView SelectedValue
zwraca wartość odpowiadającą DataKey
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. Jako dodatkowa korzyść, ustawiając SelectedIndex
element , wybrany rekord będzie przyjmować SelectedRowStyle
zdefiniowany w DataWebControls
temacie Motyw (żółte tło).
Rysunek 19. Użyj kontrolkiParameter, aby określić wartość SelectedValue elementu GridView jako źródło parametru (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, ale ProductName
pola , CategoryName
i UnitPrice
BoundFields, a następnie zmień HeaderText
właściwości na Product, Category i Price. Skonfiguruj pole UnitPrice
BoundField tak, aby jego wartość została sformatowana jako waluta. Po wprowadzeniu tych zmian znaczniki deklaratywne Panel, 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, musimy ustawić właściwość GridView SelectedIndex
na właściwość i ProductsBySupplierPanel
Panel Visible
na SelectedSuppliersIndex
true
po kliknięciu ListProducts
przycisku. Aby to osiągnąć, utwórz procedurę obsługi zdarzeń dla ListProducts
zdarzenia kontrolki Click
sieci Web przycisku i dodaj następujący kod:
protected void ListProducts_Click(object sender, EventArgs e)
{
// make sure one of the radio buttons has been selected
if (SuppliersSelectedIndex < 0)
{
ChooseSupplierMsg.Visible = true;
ProductsBySupplierPanel.Visible = false;
}
else
{
// Set the GridView's SelectedIndex
Suppliers.SelectedIndex = SuppliersSelectedIndex;
// Show the ProductsBySupplierPanel panel
ProductsBySupplierPanel.Visible = true;
}
}
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, 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 temacie Master/Detail Using a Selectable Master GridView with a DetailsView tutorial (Wybieranie elementu Master GridView) rekordy można wybrać z widoku GridView przy użyciu pola polecenia, którego ShowSelectButton
właściwość ma ustawioną wartość true
. Ale pole CommandField wyświetla przyciski jako zwykłe przyciski push, linki lub obrazy. Alternatywny interfejs użytkownika wyboru wiersza polega na podaniu przycisku radiowego lub pola wyboru w każdym wierszu GridView. W tym samouczku sprawdziliśmy, jak dodać kolumnę przycisków radiowych.
Niestety dodanie kolumny przycisków radiowych nie jest tak proste lub proste, jak można się spodziewać. Nie ma wbudowanego pola RadioButtonField, które można dodać przy 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ć klasę niestandardową DataControlField
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. W kolumnie 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 sprawdzona przez wielu pomocnych recenzentów. Główny recenzent tego samouczka był David Suru. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.