การ Binding data in GridView
ในตัวอย่างนี้จะเป็นการดึง field บาง field จาก ฐานข้อมูลมาใส่ใน GridView โดยเขียนโค้ดเอง (ไม่ใช้ SqlDataSource)
ให้สร้าง Web Application ขึ้นมา จากนั้นในหน้า Design ให้ลาก GridView มาวาง
แล้วไปที่หน้า .aspx.cs เพื่อเขียนโค้ด
(ผมใช้ ฐานข้อมูล Northwind นะครับ ถ้าใครไม่มีก็สามารถไปหา Download ได้)
ในส่วนบน ให้ ใส่ using System.Data.SqlClient;
หลังจากนั้น ไปที่ event Page_Load แล้วเขียนโค้ดดังนี้
protected void Page_Load(object sender, EventArgs e)
{
string constr = @"Server=.\SqlExpress;Database=Northwind;Integrated Security=SSPI";
string comstr = "SELECT * FROM Products ORDER BY ProductID";
SqlConnection con = new SqlConnection(constr);
SqlCommand com = new SqlCommand(comstr, con);
con.Open();
SqlDataReader reader = com.ExecuteReader();
GridView1.DataSource = reader;
GridView1.DataBind();
con.Close();
}
แล้วทดสอบรันดู
จะเห็นว่าจะแสดงข้อมูลออกมาทุก field ที่อยู่ใน Table นั้นถ้าเราต้องการให้แสดงบาง field เช่น แสดง ProductName,UnitPrice,UnitsInStock เท่านั้น
ก็ให้ใช้การ Bindind ดังนี้
ไปที่หน้า Design คลิกที่ GridView ให้คลิกตรงลูกศรด้านบนขวาแล้วเลือก Edit Column ดังรูป

หลังจากนั้นให้เอาเครื่องหมาย / หน้า Auto-generate fields ออกเพราะว่าเราจะสร้าง field เอง
ให้เลือก ที่ TemplateField ในช่อง Available fields แล้วคลิกที่ปุ่ม Add ให้ทำแบบนี้เหมือนกัน 3 ครั้งแล้วจะได้ TemplateField ออกมา
3 templateField เพราะว่าเราจะ Binding data กับfield ในฐานข้อมูล 3 field จากนั้นคลิกที่ TemplateField อันแรก
(อันบนสุด)แล้วตรง TemplateField properties ด้านขวาให้ใส่ ProductName ตรง ช่อง HeaderText เพื่อแสดงหัวข้อของ field นี้
ดังรูป

และอีก 2 templatefield ที่เหลือก็ทำเหมือนอันแรกเพียงแต่เปลียนชื่อ header text เป็นชื่ออืนคือ UnitPrice และ UnitsInStock
จากนั้นคลิก ok หลังจากนั้น กลับมาที่หน้า desing ให้คลิกที่ลูกศรด้านบนขวาอีกครั้งแล้วเลือก Edit Template แล้วนั้น ในช่อง Display จะมี template ให้เลือกต่างๆ
ดังรูป

ให้เริ่มจาก template แรกก่อน ( Column[0] - ProductName) ให้ลาก Label มาวาง ใน ItemTemplate เพื่อที่จะทำการ Binding
ดังรูป

และอีก 2 template ที่เหลือ(Unitprice,UnitsInstock) ก็ทำเหมือนกับ template แรกคือลาก label มาวาง จากนั้นก็คลิกตรงลูกศรด้านบนขวา
แล้วเลือก End Template Editing ดังรูป

แล้วไปที่หน้า Source จะเห็นว่ามีโค้ดต่างๆถูกสร้างขึ้นมาดังนี้
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="ProductName">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitPrice">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitsInStock">
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text="Label"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
ให้เขียนคำสั่ง binding ตรง Text="Label" ของ Label แต่ละ Label ดังนี้
ตัวอย่างโค้ด
<%# Bind("ProductName") %> หรือ อาจจะเขียน <%# Eval("ProductName") %>
ก็ได้
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="ProductName">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("ProductName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitPrice">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("UnitPrice") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitsInStock">
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Eval("UnitsInstock") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
แล้วทดสอบรันดูจะเห็นว่า GridView จะมี อยู่ 3 Column แต่ละ Column จะมีข้อมูลตามที่เรา Bind ไว้
***ชื่อfield ที่จะมา Bind กับ Label จะต้องเป็นชื่อ field จริงๆใน table อย่างเช่น <%# Bind("UnitPrice") %> ใน table products จะมี
ชื่อ field unitprice อยู่จริงก็สามารถเรียกใช้ได้แต่ถ้าเราเขียน <%# Bind("Unit_price") %> ถ้า field unit_price ไม่ได้อยู่ใน table products
ก็ไม่สามารถที่จะ Bind ได้
การสร้าง link และเมื่อมีการคลิกที่ link นี้ก็ ไปยังในหน้าต่อไปโดยส่งค่า ผ่าน query string ไปให้กับหน้า อื่นๆได้
สมมติว่าเราต้องการส่งค่า ProductID ในรูปแบบ query string ไปที่หน้า Page2.aspx เพื่อให้หน้า Page2.aspx นำค่า querystring
นี้ไปใช้ต่อ ก็สามารถทำได้ดังนี้
คลิกลูกศรตรงด้านบนขวาของ GridView อันเดิมแล้วเลือก Edit Column ให้เพิ่ม Template field เพื่อเข้ามาอีก 1 template field แล้ว
ใส่ header text เป็น page2 ( หรืออะไรก็ได้) จากนั้นไปที่ Edit Template เหมือนเดิมแล้วลาก Hyperlink มาวาง จากนั้น ก็ไปที่หน้า Source
จะเห็นว่ามี โค้ดถูกสร้างเพิ่มเติมเข้ามาต่อจากโค้ดอันเดิมดังนี้
<asp:TemplateField HeaderText="Page2">
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server">HyperLink</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
ให้เปลียน text ตรงคำว่า HyperLink เป็น Go to Page2
แล้วให้เพิ่ม NavigateUrl ดังนี้
<asp:TemplateField HeaderText="Page2">
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# LinkUrl(Eval("ProductId")) %>'>Go to Page2</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
ในการ Binding แบบนี้จะเป็นการส่งค่าผ่านเมธอด ไปที่เมธอดที่ชื่อ LinkUrl โดยค่าที่ส่งไป ก็คือค่าของ field ที่ชื่อ ProductID
หลังจากนั้นไปเขียนโค้ดที่ไฟล์ .aspx.cs
ดังนี้
public string LinkUrl(object productid)
{
return "~/Page2.aspx?productid=" + productid.ToString();
}
ในเมธอดนี้จะมีการส่งค่ากลับ เป็น string Url ของหน้าที่จะ link ไป(Page2.aspx)เมื่อคลิกที่ hyperlink และจะมีการส่งค่า query string ไปที่หน้า Page2.aspx
ด้วยสำหรับหน้า Page2.aspx ถ้าต้องการรับค่า query string ก็เขียนโค้ดเพื่อรับค่าของ query string ออกมา
แล้วให้ทดสอบรันดูแล้วลองคลิกที่ Hyperlink ดู
ตัวอย่างโค้ดทั้งหมด ในหน้า Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<html xmlns="
http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="ProductName">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("ProductName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitPrice">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("UnitPrice") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitsInStock">
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Eval("UnitsInstock") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Page2">
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# LinkUrl(Eval("ProductId")) %>'>Go to Page2</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br />
<br />
<br />
<br />
</div>
</form>
</body>
</html>
ตัวอย่าง โค้ดทั้งหมดในหน้า Default.aspx.cs
using System;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Data.SqlClient;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string constr = @"Server=.\SqlExpress;Database=Northwind;Integrated Security=SSPI";
string comstr = "SELECT * FROM Products ORDER BY ProductID";
SqlConnection con = new SqlConnection(constr);
SqlCommand com = new SqlCommand(comstr, con);
con.Open();
SqlDataReader reader = com.ExecuteReader();
GridView1.DataSource = reader;
GridView1.DataBind();
con.Close();
}
public string LinkUrl(object productid)
{
return "~/Page2.aspx?productid=" + productid.ToString();
}
}
การรับค่า TextBox และ การอ้างอิง control ใน GridView
(ในตัวอย่างนี้ผมจะทดสอบโดยการแสดงค่าของ TextBox เมื่อมีการคลิกที่ Button เท่านั้นนะครับถ้าต้องการนำค่าจาก TextBox ไปทำอย่างอื่นเช่น insert
ลงในฐานข้อมูลก็ให้เขียนโค้ดสำหรับการ insert เพิ่มเติมและนำค่าที่รับจาก TextBox ไปใช้)
ถ้า ต้องการให้ GridView นี้สามารถที่จะ ให้ผู้ใช้งานใส่ข้อมูลได้ผ่าน TextBox ก็สามารถทำได้ดังนี้
เข้ามาอีก 2 Template Field ( ดูจากตัวอย่างด้านบนที่เขียนมา ) แล้วลาก TextBox, Button มาวางใน Template Field นี้
ดังรูป

จากนั้นก็ให้เพิ่มคำสั่ง !this.IsPostBack ใน Page_Load ดังนี้
if (!this.IsPostBack) //สิ่งที่เพิ่มเข้ามา
{
//............โค้ดด้านล่างนี้เป็น โค้ดเดิม......................//
string constr = @"Server=.\SqlExpress;Database=Northwind;Integrated Security=SSPI";
string comstr = "SELECT * FROM Products ORDER BY ProductID";
SqlConnection con = new SqlConnection(constr);
SqlCommand com = new SqlCommand(comstr, con);
con.Open();
SqlDataReader reader = com.ExecuteReader();
GridView1.DataSource = reader;
GridView1.DataBind();
con.Close();
}//สิ่งที่เพิ่มเข้ามา
หลังจากนั้นให้เพิ่ม CommandName เข้าไปตรง Button1 ดังนี้
CommandName="showdata"
แล้วให้คลิกที่ GridView เลือก Event ที่ชื่อ RowCommand แล้วเขียนโค้ดดังนี้
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "showdata") //ตรวจสอบการคลิกที่ button ว่า CommandName เท่ากับ showdata หรือไม่ ถ้าเท่ากันก็แสดงว่ามีการคลิกที่ Button
{
for (int i = 0; i < GridView1.Rows.Count - 1; i++)
{
GridViewRow row = GridView1.Rows[i];
TextBox txt = (TextBox)row.FindControl("TextBox1"); //ชื่อ TextBox1 เป็นชื่อ ID ของ TextBox
Response.Write(txt.Text);
txt.Text = "";
}
}
}
จากนั้นก็ทดสอบรันดูให้ใส่ข้อมูลใน TextBox แล้วคลิกที่ Button แล้วทางโปรแกรมก็จะแสดง ข้อมูลใน TextBox ออกมา
ตัวอย่างโค้ดทั้งหมด หน้า Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" EnableEventValidation="false" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<html xmlns="
http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
onrowcommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField HeaderText="ProductName">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("ProductName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitPrice">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("UnitPrice") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="UnitsInStock">
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Eval("UnitsInstock") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Input Data">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Page2">
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# LinkUrl(Eval("ProductId")) %>'>Go to Page2</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Insert">
<ItemTemplate>
<asp:Button ID="Button1" CommandName="showdata" runat="server" Text="Insert" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br />
<br />
<br />
<br />
</div>
</form>
</body>
</html>
หน้า Default.aspx.cs
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
string constr = @"Server=.\SqlExpress;Database=Northwind;Integrated Security=SSPI";
string comstr = "SELECT * FROM Products ORDER BY ProductID";
SqlConnection con = new SqlConnection(constr);
SqlCommand com = new SqlCommand(comstr, con);
con.Open();
SqlDataReader reader = com.ExecuteReader();
GridView1.DataSource = reader;
GridView1.DataBind();
con.Close();
}
}
public string LinkUrl(object productid)
{
return "~/Page2.aspx?productid=" + productid.ToString();
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "showdata") //ตรวจสอบการคลิกที่ button ว่า CommandName เท่ากับ showdata หรือไม่ ถ้าเท่ากันก็แสดงว่ามีการคลิกที่ Button
{
for (int i = 0; i < GridView1.Rows.Count - 1; i++)
{
GridViewRow row = GridView1.Rows[i];
TextBox txt = (TextBox)row.FindControl("TextBox1"); //ชื่อ TextBox1 เป็นชื่อ ID ของ TextBox
Response.Write(txt.Text);
txt.Text = "";
}
}
}
}