ASP.NET: Repeater cz. 1

 

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.

Dodaj komentarz