لقد رأيت العديد من الأسئلة المماثلة أو المشابهة في المنتديات: كيف يمكنني وضع مربعات الاختيار ومربعات النص وما إلى ذلك في كل صف من DataGrid الخاص بي؟ كيفية تحديث قيمهم؟ الإجابة بسيطة جدًا، وفي هذه المقالة سأوضح لك كيفية القيام بذلك.
نعلم جميعًا أن DataGrid أداة قوية جدًا. من خلال خبرتي، يتم استخدام DataGrid في أكثر من 90% من الحالات لعرض البيانات وربما تحريرها صفًا واحدًا في كل مرة. في بعض الأحيان، قد تحتاج إلى تعديل صفوف متعددة أو حتى جميع البيانات مرة واحدة. من الأمثلة العملية على ذلك تطبيق يبيع عناصر عبر الإنترنت، حيث قد يرغب العملاء في تغيير عنصر واحد أو أكثر في سلتهم في المرة الواحدة، وذلك بالنقر فوق مربعات الاختيار لإزالة العناصر التي لا يريدونها.
المفهوم
في هذا المثال، قمت بكتابة WebForm بسيط لإدارة قائمة جهات الاتصال المخزنة في XML. الشرط بسيط للغاية: أن يكون لديك القدرة على إضافة جهات اتصال جديدة، وتعديل/حذف جهات الاتصال الموجودة. يمكن للمستخدمين تعديل أو حذف جهات اتصال متعددة مرة واحدة، كما أسمح للمستخدمين بفرز شبكة البيانات حسب الأعمدة التي يختارونها.
الأمثلة الخاصة بي مكتوبة بلغة C#. إذا كنت تفضل إصدار VB من هذه الرموز، فالرمز متوفر بكلا التنسيقين في ملف التنزيل.
يعدملف بيانات XML الموجود في
مثالContacts.xml
بسيطًا جدًا وبديهيًا.نظرًا لأن الأمر بسيط جدًا، لم أضع خطة.
<?xml version="1.0" standalone="yes"?>
<جهات الاتصال>
<الاتصال>
<Email>[email protected]</Email>
<الاسم الأول>جون</الاسم الأول>
<LastName>الظبية</LastName>
</الاتصال>
<الاتصال>
<Email>[email protected]</Email>
<الاسم الأول>جين</الاسم الأول>
<LastName>الظبية</LastName>
</الاتصال>
</Contacts>
ContactList.aspx
يعد إعداد WebForm أمرًا بسيطًا للغاية. لقد وضعت DataGrid جديدة في النموذج الخاص بي وقمت بإعداده ليحتوي على 4 أعمدة، حيث يحتوي العمود الأول على مربعات اختيار لحذف جهات الاتصال. ستلاحظ أن الشيء الرئيسي الذي قمت به هنا هو إنشاء كل عمود كعمود قالب (TemplateColumn). يتيح لي هذا وضع كائنات مربع النص ومربع الاختيار في قالب البيانات (ItemTemplate). وهذه خدعة لعرض شيء آخر غير النص في كل صف من الشبكة. بالإضافة إلى ذلك، ستلاحظ أنني أستخدم FooterTemplate لجعل إنشاء جهات اتصال جديدة أمرًا سهلاً وبديهيًا.
لقد قمت أيضًا بتضمين LinkButton لحفظ التعديلات وعمليات الحذف التي أجراها المستخدم. ولكن لا يتم استخدامه لإضافة جهات اتصال جديدة. تتم عملية إضافة جهات اتصال جديدة عن طريق زر الارتباط (LinkButton) الموجود في قالب التذييل الخاص بالعمود الأخير.
<asp:datagrid id = "dgContacts" runat = "server" ShowFooter = "True"allowSorting = "True" لون الخط الأمامي = "أسود" GridLines = "لا شيء" CellPadding = "2" لون الخط الخلفي = "LightGoldenrodYellow" BorderWidth = "1px " لون خط الحدود = "أسمر" العرض = "499px" AutoGenerateColumns = "False" DataKeyField = "البريد الإلكتروني">
<SelectedItemStyle Forefont color="GhostWhite" لون الخط الخلفي = "DarkSlateBlue"></SelectedItemStyle>
<AlternatingItemStyle Backfont color="PaleGoldenrod"></AlternatingItemStyle>
<HeaderStyle Font-Bold="True" لون الخط الخلفي = "Tan"></HeaderStyle>
<FooterStyle Backfont color="Tan"></FooterStyle>
<الأعمدة>
<asp:TemplateColumn SortExpression="FirstName" HeaderText="الاسم الأول">
<قالب العنصر>
<asp:TextBox id=First runat="server" Width="109px" Text='<%# DataBinder.Eval(Container, "DataItem.FirstName") %>'>
</asp:TextBox>
</ItemTemplate>
<قالب التذييل>
<asp:TextBox id="NewFirst" runat="server" Width="109px"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn SortExpression="LastName" HeaderText="Last Name">
<قالب العنصر>
<asp:TextBox id=Last runat="server" Width="109px" Text='<%# DataBinder.Eval(Container, "DataItem.LastName") %>'>
</asp:TextBox>
</ItemTemplate>
<قالب التذييل>
<asp:TextBox id="NewLast" runat="server" Width="109px"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn SortExpression="Email" HeaderText="Email">
<قالب العنصر>
<asp:TextBox id=Email runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Email") %>'>
</asp:TextBox>
</ItemTemplate>
<قالب التذييل>
<asp:TextBox id="NewEmail" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="حذف جهة الاتصال">
<ItemStyle HorizontalAlign="Center"></ItemStyle>
<قالب العنصر>
<asp:CheckBox Runat="server" ID="chkDelete"></asp:CheckBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Center"></FooterStyle>
<قالب التذييل>
<asp:LinkButton Runat = "server" Text = "Add" CommandName = "Add" ID = "Linkbutton1" NAME = "Linkbutton1" ></asp: LinkButton>
</FooterTemplate>
</asp:TemplateColumn>
</الأعمدة>
</asp:datagrid>
ContactList.cs
بعد أن اخترت استخدام ملف XML للوصول إلى البيانات، قررت استخدام DataSet للوصول إليه. نظرًا لأن كائن DataSet يحتوي على أساليب ReadXml وWriteXml، يعد هذا اختيارًا معقولًا للغاية. الخطوة الأولى هي قراءة البيانات في XML. كما ترون من الكود، قمت بإنشاء عضو للتعامل مع فرز البيانات.
مجموعة البيانات الخاصة _dsContacts؛
سلسلة خاصة _sSort؛
Page_Load باطلة خاصة (مرسل الكائن، System.EventArgs e)
{
// تحميل ملف XML.
_dsContacts = new DataSet();
_dsContacts.ReadXml(Server.MapPath("Contacts.xml"));
DataColumn[] dcPk = {_dsContacts.Tables["Contact"].Columns["Email"]};
_dsContacts.Tables["Contact"].PrimaryKey = dcPk
;
{
// إذا تم تحميله لأول مرة، قم بربط البيانات.
BindContacts();
_sSort = "الاسم الأول";
}
آخر
{
// بخلاف ذلك، اقرأ حالة الفرز من حالة العرض.
_sSort = (string)ViewState["Sort"];
}
}
في الخطوة الثانية، قمت بإنشاء طريقة لربط البيانات بالشبكة، والتي تضمنت منطق فرز البيانات وطرق قراءة البيانات من القرص.
BindContacts () باطلة خاصة
{
// احفظ حالة الفرز لعرض الحالة.
ViewState["Sort"] = _sSort;
// ربط الشبكة بعرض البيانات المصنفة.
DataView dv = new DataView(_dsContacts.Tables["Contact"]);
dv.Sort = _sSort;
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 == "إضافة")
{
string[] sContact = {""، ""، ""}؛
sContact[0] = ((TextBox)e.Item.FindControl("NewEmail")).Text;
sContact[1] = ((TextBox)e.Item.FindControl("NewFirst")).Text;
sContact[2] = ((TextBox)e.Item.FindControl("NewLast")).Text;
_dsContacts.Tables["Contact"].Rows.Add(sContacts
());
}
BindContacts();
}
لقد تخطيت رمز 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]);
// تحقق مما إذا كان الصف بحاجة إلى الحذف.
إذا (((CheckBox)di.FindControl("chkDelete")).تم التحقق)
{
_dsContacts.Tables["Contact"].Rows.Remove(dr);//حذف الصف المحدد
}
آخر
{
// تحديث صف البيانات.
dr["Email"] = ((TextBox)di.FindControl("Email")).Text;
dr["FirstName"] = ((TextBox)di.FindControl("First")).Text;
dr["LastName"] = ((TextBox)di.FindControl("Last")).Text;
}
}
}
// احفظه إذا كانت هناك تغييرات.
إذا (_dsContacts.HasChanges())
{
SaveContacts();
}
BindContacts();//Binding
}
الاستنتاج
يمكنني بسهولة العثور على الخلايا (الخلايا) لكل DataGridItem في عنصر التحكم من خلال موضع عنصر التحكم. هناك طرق متعددة لإنجاز ذلك، وأنا متأكد من أنه يمكنك العثور على طريقة أفضل لإنجاز هذه المهمة. كما ترون، يعد تحرير شبكة البيانات بأكملها مرة واحدة أمرًا بسيطًا للغاية. يمكن أيضًا استخدام نفس الطريقة للشبكات المرقّمة مع تعديلات طفيفة