Niedawno miałem zadanie napisania szybko aplikacji w ASP .NET Web Forms, w której miała być zaimplementowana funkcjonalność edycji wielu wierszy na raz w kontrolce DataGrid. Niestety standardowe podejście do tematu powoduje, że natrafiamy na problem.
Problem polega na tym, że standardowo można edytować tylko jeden wiersz w kontrolce DataGrid. Poniżej przykład kodu, który umożliwia wyświetlenie danych oraz ich edycje:
<asp:DataGrid runat= "server" ID="DataGrid" AutoGenerateColumns="false" OnEditCommand="Grid_EditCommand" OnUpdateCommand="DataGrid_UpdateCommand"> <Columns> <asp:BoundColumn DataField="Name" HeaderText="Imie"></asp:BoundColumn> <asp:BoundColumn DataField="Age" HeaderText="Wiek"></asp:BoundColumn> <asp:EditCommandColumn EditText="Edit" UpdateText="Update" HeaderText="Edit"></asp:EditCommandColumn> </Columns> </asp:DataGrid>
Poniżej to co się wyświetla po uruchomieniu kodu. Po naciśnięciu Edit można edytować dany wiersz. W tym przypadku edytujemy pierwszy wiersz.
Zdarzenie odpowiedzialne za edycję i zapis to Grid_EditCommand i DataGrid_UpdateCommand
protected void Grid_EditCommand(object source, DataGridCommandEventArgs e) { DataGrid.EditItemIndex = e.Item.ItemIndex; }
Zdarzenie edycji powoduje wybranie wiersza, który ma być modyfikowany. Nie mamy możliwości podania większej ilości wierszy do modyfikacji.
protected void DataGrid_UpdateCommand(object source, DataGridCommandEventArgs e) { DataStaticClass.Data[e.Item.ItemIndex].Age = short.Parse(((TextBox)e.Item.Cells[1].Controls[0]).Text); DataGrid.DataBind(); DataGrid.EditItemIndex = -1; }
Jednym z parametrów zdarzenia aktualizacji jest DataGridCommandEventArgs, który zawiera cały wiersz ze wszystkimi danymi. Na podstawie tego możemy znaleźć odpowiednią kontrolkę TextBox i wyłuskać z niej dane.
Gdybyśmy jednak chcieli edytować wszystkie wiersze na raz musimy zmienić kod na ten poniżej:
<asp:DataGrid runat= "server" ID="DataGrid2" AutoGenerateColumns="false" OnEditCommand="Grid_EditCommand" OnUpdateCommand="DataGrid_UpdateCommand"> <Columns> <asp:TemplateColumn HeaderText="Imie"> <ItemTemplate> <asp:TextBox runat="server" Text='<%# Eval("Name")%>'></asp:TextBox> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderText="Wiek"> <ItemTemplate> <asp:TextBox ID="TextBox2" runat="server" Text='<%# Eval("Age")%>'></asp:TextBox> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid>
Musimy użyć tutaj znacznika asp:TemplateColumn i ItemTemplate a następnie włożyć kontolkę TextBox. Teraz gdy uruchomimy kod otrzymamy następujący efekt:
Od razu po załadowaniu strony wszystkie pola są edytowane.
Jedyne co zostało nam do zrobienia to przycisk „Zapisz” aby zapisać dane. Przycisk należy umieścić gdzieś po za kontrolką DataGrid.
Kod poniżej:
protected void btnZapisz_Click(object sender, EventArgs e) { foreach (DataGridItem item in DataGrid1.Items) { DataStaticClass.Data[item.ItemIndex].Age = short.Parse(((TextBox)item.Cells[1].Controls[1]).Text); } }
Aby modyfikować wszystkie elementy przechodzimy po wszystkich elementach kontroliki DataGrid.Items i wyłuskujemy potrzebne dane podobnie jak to robiliśmy w poprzednim przypadku.
Dodatkowo pod tym linkiem znajduje się bardziej rozbudowany artykuł o tworzeniu edytowalnego DataGrid-a.
Są tam opisane takie rozwiązania jak budowa własnej kontrolki DataGrid, która umożliwia edycję wszystkich wierszy.