Tôi quyết định viết bài viết này bởi vì có nhiều người đã hỏi rất nhiều. Về cơ bản, ví dụ này cho thấy làm thế nào để tạo hàng trong GridView với textbox khi nhập dữ liệu trên Textbox, và xử lý sự kiện thay đổi nội dung trên Textbox để thêm hàng cho hợp lý.
Để bắt đầu, chúng ta hãy lấy điều khiển GridView từ Toolbox trực quan và đặt nó trong Web.
<asp:GridView ID="Gridview1" runat="server" ShowFooter="true" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
<asp:TemplateField HeaderText="Header 1">
<ItemTemplate>
<asp:TextBox ID="TextBox1" AutoPostBack="true" OnTextChanged="TextChangedEvent" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 2">
<ItemTemplate>
<asp:TextBox ID="TextBox2" AutoPostBack="true" OnTextChanged="TextChangedEvent" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 3">
<ItemTemplate>
<asp:TextBox ID="TextBox3" AutoPostBack="true" OnTextChanged="TextChangedEvent" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Từ bản demo này tạo ra hàng TextBox trong GridView, sau đó chúng ta thiết lập một số cột Template để GridView tự động tạo ra các textbox khi hàng mới được bổ sung.
Như bạn có thể thấy tôi đã thiết lập cột BoundField để hiển thị số hàng và thiết lập ba cột TemplateField trong Gridview và thêm vào mỗi cột một điều khiển TextBox.
Bây giờ chúng ta hãy chuyển sang Code behind bên trong cs.
Điều khiển GridView sẽ không hiển thị trong trang khi không có dữ liệu liên quan trên nó. Vì vậy, điều đầu tiên chúng ta cần ở đây là thiết lập dữ liệu trong điều khiển GridView. Để làm điều này, chúng ta có thể sử dụng DataTable cho các ràng buộc GridView.
private void SetInitialRow()
{
DataTable dt = new DataTable();
DataRow dr = null;
dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
dt.Columns.Add(new DataColumn("Column1", typeof(string)));
dt.Columns.Add(new DataColumn("Column2", typeof(string)));
dt.Columns.Add(new DataColumn("Column3", typeof(string)));
dr = dt.NewRow();
dr["RowNumber"] = 1;
dr["Column1"] = string.Empty;
dr["Column2"] = string.Empty;
dr["Column3"] = string.Empty;
dt.Rows.Add(dr);
//dr = dt.NewRow();
//Store the DataTable in ViewState
ViewState["CurrentTable"] = dt;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
Như bạn thấy, chúng ta xác định bốn cột trong DataTable được gọi là RowNumber, Column1, COLUMN2 và Column3. Cột RowNumber sẽ phục vụ như là chìa khóa để tạo ra các hàng trong GridView. Cột 1, 2 và 3, tôi được giao giá trị rỗng cho các cột từ GridView sẽ được tạo ra lần đầu tiên. Bạn thấy rằng tôi lưu trữ các DataTable trong ViewState để tôi có thể tham khảo các dữ liệu hiện có liên quan trong DataTable khi postbacks.
Bây giờ chúng ta hãy gọi các phương thức trong sự kiện Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
SetInitialRow();
}
}
Chạy mã trên sẽ cho chúng ta kết quả này dưới đây:
Bây giờ tạo phương thức để tạo ra các hàng khi Text được thay đổi. Dưới đây là cách:
private void AddNewRowToGrid()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
//extract the TextBox values
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = i + 1;
dtCurrentTable.Rows[i - 1]["Column1"] = box1.Text;
dtCurrentTable.Rows[i - 1]["Column2"] = box2.Text;
dtCurrentTable.Rows[i - 1]["Column3"] = box3.Text;
rowIndex++;
}
dtCurrentTable.Rows.Add(drCurrentRow);
ViewState["CurrentTable"] = dtCurrentTable;
Gridview1.DataSource = dtCurrentTable;
Gridview1.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
//Set Previous Data on Postbacks
SetPreviousData();
}
Mã trên được các dữ liệu trước đó lưu trữ từ các ViewState và thiết lập các dữ liệu được lưu trữ từ nó vào một DataTable để chúng ta có thể thêm một hàng mới dựa vào giá trị nhập từ TextBox.
Bạn cũng sẽ nhận thấy rằng chúng ta gọi là phương thức SetPreviousData() ở phần dưới cùng của mã trên.
private void SetPreviousData()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
box1.Text = dt.Rows[i]["Column1"].ToString();
box2.Text = dt.Rows[i]["Column2"].ToString();
box3.Text = dt.Rows[i]["Column3"].ToString();
rowIndex++;
}
}
}
}
Phương thức được thiết lập.
protected void TextChangedEvent(object sender, EventArgs e)
{
TextBox thisTextBox = (TextBox)sender;
GridViewRow thisGridViewRow = (GridViewRow)thisTextBox.Parent.Parent;
int row = thisGridViewRow.RowIndex;
if (row == Gridview1.Rows.Count-1)
{
AddNewRowToGrid();
}
}
OK, vậy là chúng ta đã giải quyết xong bài toán. Phía dưới là hình ảnh minh họa mà ta đã làm được trong bài viết này: