ฉันเคยเห็นคำถามเดียวกันหรือคล้ายกันมากมายในฟอรัม: ฉันจะวางช่องทำเครื่องหมาย กล่องข้อความ ฯลฯ ในแต่ละแถวของ DataGrid ได้อย่างไร จะอัพเดตค่าของพวกเขาได้อย่างไร? คำตอบนั้นค่อนข้างง่าย และในบทความนี้ ฉันจะแสดงให้คุณเห็นว่าต้องทำอย่างไร
เราทุกคนรู้ดีว่า DataGrid เป็นเครื่องมือที่ทรงพลังมาก จากประสบการณ์ของผม มากกว่า 90% ของเวลา DataGrid ใช้เพื่อแสดงข้อมูลและอาจแก้ไขได้ทีละแถว บางครั้ง คุณอาจต้องแก้ไขหลายแถวหรือแก้ไขข้อมูลทั้งหมดพร้อมกัน ตัวอย่างที่เป็นประโยชน์คือในแอปพลิเคชันที่ขายสินค้าออนไลน์ ซึ่งลูกค้าอาจต้องการเปลี่ยนสินค้าในตะกร้าทีละรายการขึ้นไป โดยคลิกที่ช่องทำเครื่องหมายเพื่อลบสินค้าที่ไม่ต้องการ
แนวคิด
ในตัวอย่างนี้ ฉันเขียน WebForm อย่างง่ายเพื่อจัดการรายชื่อผู้ติดต่อที่จัดเก็บไว้ใน XML ข้อกำหนดนั้นง่ายมาก: มีความสามารถในการเพิ่มผู้ติดต่อใหม่ แก้ไข/ลบผู้ติดต่อที่มีอยู่ ผู้ใช้สามารถแก้ไขหรือลบผู้ติดต่อหลายรายพร้อมกันได้ และฉันยังอนุญาตให้ผู้ใช้จัดเรียงตารางข้อมูลตามคอลัมน์ที่พวกเขาเลือกอีกด้วย
ตัวอย่างของฉันเขียนด้วยภาษา C# หากคุณต้องการโค้ดเหล่านี้ในเวอร์ชัน VB โค้ดจะมีอยู่ในทั้งสองรูปแบบในไฟล์ดาวน์โหลด
ไฟล์ข้อมูล XML ใน
ตัวอย่างContacts.xml
นั้นเรียบง่ายและใช้งานง่ายมากเนื่องจากมันง่ายมาก ฉันจึงไม่ได้สร้างแผนขึ้นมา
<?xml version="1.0" แบบสแตนด์อโลน = "ใช่"?>
<ผู้ติดต่อ>
<ติดต่อ>
<อีเมล>[email protected]</อีเมล>
<FirstName>จอห์น</FirstName>
<นามสกุล>โด</นามสกุล>
</ติดต่อ>
<ติดต่อ>
<อีเมล>[email protected]</Email>
<FirstName>เจน</FirstName>
<นามสกุล>โด</นามสกุล>
</ติดต่อ>
</ผู้ติดต่อ>
ContactList.aspx
การตั้งค่า WebForm นั้นง่ายมาก ฉันวาง DataGrid ใหม่ลงในแบบฟอร์มของฉันและตั้งค่าให้มี 4 คอลัมน์ โดยคอลัมน์แรกมีช่องทำเครื่องหมายสำหรับลบผู้ติดต่อ คุณจะสังเกตเห็นว่าสิ่งสำคัญที่ฉันทำที่นี่คือสร้างแต่ละคอลัมน์เป็นคอลัมน์เทมเพลต (TemplateColumn) สิ่งนี้ช่วยให้ฉันวางกล่องข้อความและวัตถุช่องทำเครื่องหมายลงในเทมเพลตข้อมูล (ItemTemplate) นี่เป็นเคล็ดลับในการแสดงสิ่งอื่นที่ไม่ใช่ข้อความในแต่ละแถวของตาราง นอกจากนี้ คุณจะสังเกตเห็นว่าฉันใช้ FooterTemplate เพื่อทำให้การสร้างผู้ติดต่อใหม่เป็นเรื่องง่ายและใช้งานง่าย
ฉันยังรวม LinkButton เพื่อบันทึกการแก้ไขและการลบที่ทำโดยผู้ใช้ แต่ไม่ได้ใช้เพื่อเพิ่มผู้ติดต่อใหม่ การดำเนินการเพิ่มผู้ติดต่อใหม่จะเสร็จสิ้นโดยปุ่มลิงก์ (LinkButton) ในเทมเพลตส่วนท้ายของคอลัมน์สุดท้าย
<asp:datagrid id = "dgContacts" runat = "เซิร์ฟเวอร์" ShowFooter = "True" AllowSorting = "True" Forefont color = "Black" GridLines = "ไม่มี" CellPadding = "2" Backfont color = "LightGoldenrodYellow" BorderWidth = "1px " Borderfont color="Tan" width="499px" AutoGenerateColumns="False" DataKeyField="อีเมล">
<SelectedItemStyle Forefont color="GhostWhite" Backfont color="DarkSlateBlue"></SelectedItemStyle>
<AlternatingItemStyle Backfont color="PaleGoldenrod"></AlternatingItemStyle>
<HeaderStyle Font-Bold="True" Backfont color="Tan"></HeaderStyle>
<FooterStyle Backfont color="Tan"></FooterStyle>
<คอลัมน์>
<asp:TemplateColumn SortExpression="FirstName" HeaderText="ชื่อ">
<เทมเพลตรายการ>
<asp:TextBox id=First runat="server" width="109px" Text='<%# DataBinder.Eval(คอนเทนเนอร์, "DataItem.FirstName") %>'>
</asp:กล่องข้อความ>
</เทมเพลตรายการ>
<เทมเพลตส่วนท้าย>
<asp:TextBox id="NewFirst" runat="server" width="109px"></asp:TextBox>
</เทมเพลตส่วนท้าย>
</asp:TemplateColumn>
<asp:TemplateColumn SortExpression="นามสกุล" HeaderText="นามสกุล">
<เทมเพลตรายการ>
<asp:TextBox id=Last runat="server" width="109px" Text='<%# DataBinder.Eval(คอนเทนเนอร์, "DataItem.LastName") %>'>
</asp:กล่องข้อความ>
</เทมเพลตรายการ>
<เทมเพลตส่วนท้าย>
<asp:TextBox id="NewLast" runat="server" width="109px"></asp:TextBox>
</เทมเพลตส่วนท้าย>
</asp:TemplateColumn>
<asp:TemplateColumn SortExpression="อีเมล" HeaderText="อีเมล">
<เทมเพลตรายการ>
<asp:TextBox id=อีเมล runat="server" Text='<%# DataBinder.Eval(คอนเทนเนอร์, "DataItem.Email") %>'>
</asp:กล่องข้อความ>
</เทมเพลตรายการ>
<เทมเพลตส่วนท้าย>
<asp:TextBox id="NewEmail" runat="server"></asp:TextBox>
</เทมเพลตส่วนท้าย>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="ลบผู้ติดต่อ">
<ItemStyle HorizonAlign="Center"></ItemStyle>
<เทมเพลตรายการ>
<asp:CheckBox Runat="เซิร์ฟเวอร์" ID="chkDelete"></asp:CheckBox>
</เทมเพลตรายการ>
<FooterStyle HorizonAlign="Center"></FooterStyle>
<เทมเพลตส่วนท้าย>
<asp:LinkButton Runat = "เซิร์ฟเวอร์" Text = "เพิ่ม" CommandName = "เพิ่ม" ID = "Linkbutton1" NAME = "Linkbutton1" ></asp:LinkButton>
</เทมเพลตส่วนท้าย>
</asp:TemplateColumn>
</คอลัมน์>
</asp:datagrid>
ContactList.cs
หลังจากที่ฉันเลือกใช้ไฟล์ XML เพื่อเข้าถึงข้อมูล ฉันตัดสินใจใช้ชุดข้อมูลเพื่อเข้าถึงข้อมูล เนื่องจากวัตถุ DataSet มีเมธอด ReadXml และ WriteXml นี่จึงเป็นตัวเลือกที่สมเหตุสมผลมาก ขั้นตอนแรกคือการอ่านข้อมูลในรูปแบบ XML อย่างที่คุณเห็นจากโค้ด ฉันได้สร้างสมาชิกขึ้นมาเพื่อจัดการการเรียงลำดับข้อมูล
ชุดข้อมูลส่วนตัว _dsContacts;
สตริงส่วนตัว _sSort;
โมฆะส่วนตัว Page_Load (ผู้ส่งวัตถุ System.EventArgs e)
-
//โหลดไฟล์ XML
_dsContacts = ชุดข้อมูลใหม่ ();
_dsContacts.ReadXml(Server.MapPath("Contacts.xml"));
DataColumn[] dcPk = {_dsContacts.Tables["Contact"].Columns["อีเมล"]};
_dsContacts.Tables["ติดต่อ"].PrimaryKey = dcPk;
if (!Page.IsPostBack )
-
// ถ้าโหลดครั้งแรก ให้ผูกข้อมูล
ผูกผู้ติดต่อ();
_sSort = "ชื่อ";
-
อื่น
-
// มิฉะนั้น ให้อ่านสถานะการเรียงลำดับจากสถานะมุมมอง
_sSort = (สตริง)ViewState["เรียงลำดับ"];
-
-
ในขั้นตอนที่สอง ฉันสร้างวิธีการผูกข้อมูลเข้ากับกริด ซึ่งรวมถึงตรรกะการเรียงลำดับข้อมูลและวิธีการอ่านข้อมูลจากดิสก์
BindContacts เป็นโมฆะส่วนตัว ()
-
//บันทึกสถานะการเรียงลำดับเพื่อดูสถานะ
ViewState["Sort"] = _sSort;
// ผูกตารางเข้ากับมุมมองข้อมูลที่เรียงลำดับ
DataView dv = DataView ใหม่ (_dsContacts.Tables ["ติดต่อ"]);
dv.เรียงลำดับ = _sเรียงลำดับ;
dgContacts.DataSource = dv;
dgContacts.DataBind();
} }
โมฆะส่วนตัว SaveContacts()
-
_dsContacts.WriteXml(Server.MapPath("Contacts.xml"));
}
เหตุการณ์ ItemCommand ใช้เพื่อจัดการการเพิ่มผู้ติดต่อใหม่ลงในรายการ หมายเหตุ: ฉันตรวจสอบว่าพารามิเตอร์ CommandName เป็น Add หรือไม่ เพื่อจัดการค่าส่งคืนของปุ่มลิงก์ (LinkButton) ในเทมเพลตส่วนท้าย (FooterTemplate) ของคอลัมน์สุดท้ายของตารางในหน้า ASPX
โมฆะส่วนตัว dgContacts_ItemCommand (แหล่งวัตถุ, System.Web.UI.WebControls.DataGridCommandEventArgs e)
-
//เพิ่มข้อมูลใหม่ลงในชุดข้อมูล ที่นี่ฉันใช้อาร์เรย์เพื่อปรับปรุงประสิทธิภาพการประมวลผล
ถ้า (e.CommandName == "เพิ่ม")
-
สตริง [] sContact = {"", "", ""};
sContact[0] = ((TextBox)e.Item.FindControl("NewEmail")).ข้อความ;
sContact[1] = ((TextBox)e.Item.FindControl("NewFirst")).ข้อความ;
sContact[2] = ((TextBox)e.Item.FindControl("NewLast")).Text;
_dsContacts.Tables["Contact"].Rows.Add(sContacts
();
}
ผูกรายชื่อ();
}
ฉันข้ามโค้ด SortCommand เนื่องจากมีเอกสารอื่นๆ อีกมากมายที่กล่าวถึงการเรียงลำดับอย่างละเอียด หากคุณดาวน์โหลดซอร์สโค้ดสำหรับตัวอย่างนี้ ก็จะรวมอยู่ด้วย
ในที่สุด ฉันย้ายเหตุการณ์การคลิก (onClick) ของปุ่มลิงก์ (LinkButton) บนแบบฟอร์มที่นี่ ที่นี่ฉันวนซ้ำรายการข้อมูลใน DataGrid เพื่อดำเนินการลบและอัปเดตที่จำเป็น
โมฆะส่วนตัว btnUpdate_Click (ผู้ส่งวัตถุ System.EventArgs e)
-
// วนซ้ำแต่ละรายการข้อมูล
foreach (DataGridItem ใน dgContacts.Items)
-
// ตรวจสอบให้แน่ใจว่าเป็นรายการข้อมูลและไม่ใช่ด้านบนหรือด้านล่างของหน้า
ถ้า (di.ItemType == ListItemType.Item || di.ItemType == ListItemType.AlternatingItem)
-
// รับแถวปัจจุบันหลังจากดำเนินการอัพเดตหรือลบ
DataRow dr = _dsContacts.Tables["Contact"].Rows.Find(dgContacts.DataKeys[di.ItemIndex]);
// ตรวจสอบว่าจำเป็นต้องลบแถวหรือไม่
ถ้า (((ช่องทำเครื่องหมาย)di.FindControl("chkDelete")).ตรวจสอบแล้ว)
-
_dsContacts.Tables["Contact"].Rows.Remove(dr);//ลบแถวที่ระบุ
-
อื่น
-
//อัพเดตแถวข้อมูล
dr["อีเมล"] = ((TextBox)di.FindControl("อีเมล")).ข้อความ;
dr["FirstName"] = ((TextBox)di.FindControl("First")).ข้อความ;
dr["นามสกุล"] = ((TextBox)di.FindControl("Last")).ข้อความ;
-
-
}
//บันทึกไว้หากมีการเปลี่ยนแปลง
ถ้า (_dsContacts.HasChanges())
-
บันทึกผู้ติดต่อ();
}
BindContacts();//Binding
}
สรุป
ฉันสามารถค้นหาเซลล์ (เซลล์) ของแต่ละ DataGridItem ในตัวควบคุมได้อย่างง่ายดายผ่านตำแหน่งของตัวควบคุม มีหลายวิธีในการบรรลุเป้าหมายนี้ และฉันแน่ใจว่าคุณจะสามารถหาวิธีที่ดีกว่าในการบรรลุภารกิจนี้ได้ อย่างที่คุณเห็น การแก้ไขตารางข้อมูลทั้งหมดพร้อมกันนั้นง่ายมาก วิธีการเดียวกันนี้ยังสามารถใช้กับกริดที่มีการแบ่งหน้าโดยมีการแก้ไขเล็กน้อย