ASP.NET: Repeater cz. 1
20 listopada, 2010 Dodaj komentarz
W kolejnych dwóch postach postaram opisać się moje zmagania z kontrolką ASP.NET o nazwie repeater. Z racji dużej liczby kodu, jaki będzie zamieszczony postanowiłem w niniejszym poście zrobić wprowadzenie, w drugim zaś objaśnić większość implementacji dla postawionego zadania. Zadaniem tym jest stworzenie funkcjonalności, dzięki której pola tekstowe na stronie mogłyby być dodawane w razie potrzeby w nieskończoność. Chcemy zatem dysponować z góry nieznaną liczbą pól, jednak o znanym charakterze. Prościej mówiąc potrzebne są pola tekstowe znajdujące się w wierszach, przy czym liczba wierszy w momencie uruchomienia aplikacji nie jest znana. Wiąże się z tym konieczność zaimplementowania funkcji:
-
dodawania nowego wiersza bo kliknięciu w przycisk
-
usuwania wybranego wiersza z danymi
-
odczytu istniejących danych (w przykładzie, dla uproszczenia, z własnej kolekcji)
-
zapisu danych znajdujących się w polach do kolekcji (de facto jest to punkt pierwszy z wymienionych stąd nie będzie szczegółowo wyjaśniony)
Postanowiłem do tego zadania, aby się czegoś nauczyć, wykorzystać kontrolkę zwaną repeaterem.
Pierwszym krokiem będzie zatem stworzenie własnej kolekcji, przechowującej informacje, powiedzmy pobrane uprzednio z bazy danych. Kolekcja ta ma prostą strukturę, mianowicie ma przechowywać dwa pola – id oraz nazwę, czyli jest w pewnym tego słowa znaczeniu słownikiem. Elementem kolekcji będą obiekty klasy SimpleItem:
[Serializable] public class SimpleItem { /// <summary> /// Default constructor /// </summary> public SimpleItem() { this.id = 0; this.name = null; } /// <summary> /// Constructor using id and name /// </summary> /// <param name="id">Id</param> /// <param name="name">Name</param> public SimpleItem(int id, string name) { this.id = id; this.name = name; } private int id; /// <summary> /// Id /// </summary> public int Id { get { return this.id; } set { this.id = value; } } private string name; /// <summary> /// Name /// </summary> public string Name { get { return this.name; } set { this.name = value; } } }
Zwracam w powyższym kodzie uwagę na znajdujący się na początku atrybut [Serializable], aczkolwiek w tym poście pozwolę sobie go nie omawiać 🙂 Przypominam równiez o konieczności stworzenia własnej implementacji konstruktora domyślnego, w przypadku gdy stworzony został niedomyślny.
Kolekcja takich elementów tworzona jest w sposób następujący:
//using System.Collections.ObjectModel Collection<SimpleItem> myCollection = new Collection<SimpleItem>();
Przy czym należy pamiętać od dodaniu na początku odpowiedniej przestrzenii nazw. Na potrzeby przedstawionych rozważań, z metod obiektu typu Collection, interesować nas będzie jedynie metod pozwalająca na dodawanie elementów do kolekcji, czyli Add().
Teraz odrobina informacji o tworzeniu repeatera. Po wstawieniu kontrolki:
<asp:Repeater ID="repDynamicRows" runat="server"></asp:Repeater>
należy zdefiniować, jak będzie wyglądał nagłówek oraz jaką postać będzie miał każdy wiersz. Część nagłówkową definiujemy wykorzystując tabele html pomiędzy znacznikami <HeaderTemplate></HeaderTemplate>
<HeaderTemplate> <table> <tr> <td style="width:100px">Id</td> <td style="width:100px">Nazwa</td> </tr> </table> </HeaderTemplate>
Natomiast to, jak będzie wyglądał każdy wiersz repeatera podajemy w części pomiędzy znacznikami <ItemTemplate></ItemTemplate>
<ItemTemplate> <table> <tr> <td style="width:100px"><asp:TextBox ID="txtId" runat="server" Width="100" Text='<%# Eval("Id") %>'></asp:TextBox></td> <td style="width:100px"><asp:TextBox ID="txtName" runat="server" Width="100" Text='<%# Eval("Name") %>'></asp:TextBox></td> <td style="width:100px"><asp:LinkButton ID="lkbDelete" runat="server" CommandName="Delete">X</asp:LinkButton></td> </tr> </table> </ItemTemplate>
W tym przypadku repeater składał będzie się z dwóch pól tekstowych, umożliwiających edycję kolumny Id oraz Nazwa. W trzeciej kolumnie znajdować będzie się przycisk, którego zadaniem ma być skasowanie wiersza, w którym się on znajduje. Za pomocą obiektu typu LinkButton można zdefiniować nazwę wykonywanej akcji po jego naciśnięciu, stąd właściwość CommandName=”Delete” (tak naprawdę nazwa może być dowolna, chodzi tylko o pewien sposób rozróżniania wykonywanej komendy). W pozostałych dwóch przypadkach, czyli dla pól tekstowych zdefiniowana została właściwość Text, która za pomocą metody Eval(), powoduje wpisanie do pola tekstowego odpowiedniego pola z elementu stworzonej kolekcji, właściwego dla danego wiersza kontrolki.
Dane, które mają wypełniać kontrolkę repeater, jeśli istnieją, podpinane są pod nią w odpowiednim momencie, czyli:
protected void Page_Load(object sender, EventArgs e) { //Set collection only at the first load if (!IsPostBack) { Collection<SimpleItem> myCollection = new Collection<SimpleItem>(); myCollection.Add(new SimpleItem(1, "Pierwszy")); myCollection.Add(new SimpleItem(2, "Drugi")); //Bind collection to repeater repDynamicRows.DataSource = myCollection; repDynamicRows.DataBind(); } }
cdn.