Udostępnij za pośrednictwem


Dodawanie kolumny przycisków radiowych do kontrolki GridView (C#)

Autor: Scott Mitchell

Pobierz plik PDF

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

Dodawanie stron ASP.NET dla samouczków dotyczących SqlDataSource-Related

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.

Dodaj kontrolkę Użytkownika SectionLevelTutorialListing.ascx, aby Default.aspx

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

Mapa witryny zawiera teraz wpisy dotyczące ulepszania samouczków GridView

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

Tworzenie nowego obiektuDataSource o nazwie SuppliersDataSource

Rysunek 4. Tworzenie nowego obiektuDataSource nazwane SuppliersDataSource (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Zrzut ekranu przedstawiający okno Konfigurowanie źródła danych — SuppliersDataSource z zaznaczonym obiektem biznesowymBLL i wyróżnionym przyciskiem Dalej.

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.

Zrzut ekranu przedstawiający okno Konfigurowanie źródła danych — SuppliersDataSource z otwartą kartą SELECT. Opcja metody GetSupplierByCountry jest zaznaczona, a przycisk Dalej jest wyróżniony.

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.

Zrzut ekranu przedstawiający okno Konfigurowanie źródła danych — SuppliersDataSource z otwartą kartą UPDATE. Opcja metody (Brak) jest zaznaczona, a przycisk Dalej jest wyróżniony.

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.

Użyj usa jako wartości domyślnej dla parametru kraju

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 , CompanyNameCityi 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.

Dostawcy z USA mają swoje nazwy, miasto i informacje o kraju wymienione

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.

Dodawanie kontrolki sieci Web RadioButton do elementu ItemTemplate

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 ItemTemplateelementu , 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.

Przyciski radiowe GridView nie są grupowane

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 IDi formularzy IDsieci 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 RowCreatedRowDataBound 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, ItemTemplatezastępując go kontrolką Literał. Ustaw kontrolkę Literał na IDRadioButtonMarkupwartość .

Dodawanie kontrolki literału do elementu ItemTemplate

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 valuewierszy 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.RowIndexró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 -1to , 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 falsei 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 truewartość .

Dodawanie kontrolki sieci Web etykiety nad kontrolką GridView

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.

Etykieta ChooseSupplierMsg jest wyświetlana, jeśli nie wybrano dostawcy

Rysunek 14. Etykieta jest wyświetlana ChooseSupplierMsg , jeśli nie wybrano dostawcy (kliknij, aby wyświetlić obraz w pełnym rozmiarze)

Wybrane produkty dostawcy są wyświetlane w ProductsForSupplierDetails.aspx

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ść falsena 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.

Wiązanie elementu ProductsBySupplier GridView z nowym obiektemDataSource

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.

Konfigurowanie obiektu ObjectDataSource do używania metody GetProductsBySupplierID(supplierID)

Rysunek 17. Konfigurowanie obiektu ObjectDataSource do użycia GetProductsBySupplierID(supplierID) metody (kliknij, aby wyświetlić obraz pełnowymiarowy)

Ustaw Drop-Down Listy na wartość (Brak) na kartach UPDATE, INSERT i DELETE

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ą DataKeySelectedIndex 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 SelectedIndexelement , wybrany rekord będzie przyjmować SelectedRowStyle zdefiniowany w DataWebControls temacie Motyw (żółte tło).

Użyj parametru ControlParameter, aby określić wartość SelectedValue elementu GridView jako źródło parametru

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 ProductNamepola , CategoryNamei 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 SelectedSuppliersIndextrue 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.

Produkty dostarczone przez Bigfoot Breweries są wymienione na tej samej 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.