استفاده از کنترل Asynchronous GridView چندگانه (تو درتو) در Asp.Net
پنجشنبه 29 بهمن 1394در این مقاله موارد استفاده از GridView در صفحات وب Asp.Net ، و نمونه هایی از دو کنترل Grid View آسنکرون(غیر همزمان) تک و تودرتو ارائه میشود که براساس نیاز می توان از دو حالت موجود این کنترل استفاده کرد.
کنترل Grid View یکی از مولفه های پیچیده و منبع سنگین است که میتوانیم در صفحات وب Asp.Net از آن ها استفاده کنیم. کنترل Grid View به آسانی داده های پیچیده با ستون هاو ردیفهای متعدد را به صورت سفارشی طراحی و با ظاهری مناسب(بصورت جدول) میسازد. برای هر کسی که نیاز به استفاده از کنترل Grid View دارد. بسیار مهم است که درک خوبی از سرور و کلاینت داشته باشد.
استفاده از کد
در قسمت اول با یک grid تک که نیاز به بروز رسانی آسنکرون دارد شروع میکنیم.
مورد دوم grid های چندگانه ویا تودرتو است که نیاز به بروز رسانی یک به یک، با رویداد chaining در زمان اجرای جاوا اسکریپت دارد. این به این معنی است که ما تنها می توانیم به روز رسانی آسنکرون از grid دوم را پس از پایان به روز رسانی اولین grid به انجام برسانیم.
کنترل (گرید ویو واحد)Single Grid View
کنترل Grid View در داخل update panel موجود است. برای ساختgrid بمنظور بروز رسانی async نیازبه update panel داریم . Grid تولید شده توسط کد ، تست داده را انجام میدهد. اگر می خواهید تست قوی داشته باشید می توانید منبع داده grid را به جدول پایگاه داده واقعی اتصال دهید.
برای افزودن رکورد های بیشتر به grid ،از یک ورودی میتوانید استفاده کنید. به ازای ورود یک رکورد باید grid را به روز رسانی کنیم..
از __doPostBack برای بروزرسانی grid در کدهای جاوا اسکریپت استفاده کرده ایم ، در این مثال برای درک بهتر از doPostBack برای grid های تورد تو استفاده میشود .
پروژه ی Asp.Netجدیدی ایجاد کرده و سپس فرم وب empty را انتخاب میکنیم. درون پروژه یک صفحه بنام SingleGrid.aspx اضافه کرده ، داخل این صفحه یک update panel بنام upMain و در داخل update panel یک کنترل Grid View و بنام gridMain اضافه میکنیم.
برای گرفتن نام ورودی و افزودن به داده ها یک text box اضافه میکنیم. همچنین درhtml ،یک رویداد کلیک برای اتصال تابع جاوا اسکریپت ، برای فراخوانی تابع __doPostBack اضافه میکنیم.
ما نیاز به اتصال ، رویداد افزودن یک رکورد جدید به داده ها و سپس به روز رسانی کنترل grid داریم . اتصال رویداد DOMContentLoaded با تابع onload و رویداد کلیک با استفاده از تابع AddRecord برقرار میسازد. تابع AddRecord هنگام فراخوانی تابع __doPostBack بصورت آسنکرون upMain را در update panel ، بروزرسانی میکند.
SingleGrid.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SingleGrid.aspx.cs" Inherits="WebApplication.SingleGrid" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> </head> <body dir="rtl"> <form runat="server" > <div style="padding: 100px" style="border-style:groove"> <asp:ScriptManager ID="scriptManager1" runat="server" AsyncPostBackTimeout="90"></asp:ScriptManager> <h3>تمام رکوردها</h3> <asp:UpdatePanel ID="upMain" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:GridView ID="gridMain" runat="server" OnDataBinding="gridMain_DataBinding" CellPadding="4" ForeColor="#333333" GridLines="None"> <AlternatingRowStyle BackColor="White" /> <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" /> <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" /> <RowStyle BackColor="#FFFBD6" ForeColor="#333333" /> <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" /> <SortedAscendingCellStyle BackColor="#FDF5AC" /> <SortedAscendingHeaderStyle BackColor="#4D0000" /> <SortedDescendingCellStyle BackColor="#FCF6C0" /> <SortedDescendingHeaderStyle BackColor="#820000" /> </asp:GridView> </ContentTemplate> </asp:UpdatePanel> <br/> <br/> <h3>اضافه کردن رکورد جدید</h3> <input id="txtName" type="text" placeholder="نام را وارد کنید" /> <br /> <a href="#" id="lnkAddRecord" >اضافه کردن</a> </div> </form> <script> var upMainID = '<%= upMain.ClientID%>'; document.addEventListener("DOMContentLoaded", onLoad); var lnkAddRecord = null; function onLoad() { lnkAddRecord = document.querySelector('#lnkAddRecord'); lnkAddRecord.addEventListener('click', AddRecord); } function AddRecord() { var txtName = document.querySelector('#txtName'); __doPostBack(upMainID, txtName.value); return false; } </script> </body> </html>
در بالا برای ارسال دو آرگومان، به eventArgument نیاز داریم.
اضافه کردن متدها در فایل .cs برای رویداد اتصال داده ها است. برای تست داده ، کد و متدی به نام SetData ایجاد میکنیم. از متد AddRecord برای افزودن یک رکورد جدید به جدول استفاده می شود. این جدول در application session state ذخیره می شود به طوری که ما می توانیم این اطلاعات را در postback های جزئی پس از آن بازیابی کنیم.
SingleGrid.aspx.cs
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebApplication { public partial class SingleGrid : System.Web.UI.Page { private DataTable _table; /// <summary> /// Page load event /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { SetData(); } else { String parameter = Request["__EVENTARGUMENT"]; AddRecord(parameter); } gridMain.DataBind(); } /// <summary> /// Grid data binding event /// </summary> /// <param name="e"></param> protected void gridMain_DataBinding(object sender, EventArgs e) { gridMain.DataSource = (Session["MainTable"] as DataTable).DefaultView; } /// <summary> /// Sets the sample data table /// </summary> /// <returns></returns> private void SetData() { _table = new DataTable(); _table.Columns.Add("ID", typeof(Int32)); _table.Columns.Add("نام", typeof(String)); _table.Rows.Add(1, "کلثوم ابراهیمی"); _table.Rows.Add(2, "مینا بحری"); Session["MainTable"] = _table; } /// <summary> /// Adds a new student record /// </summary> /// <param name="name"></param> private void AddRecord(String name) { DataTable table = Session["MainTable"] as DataTable; table.Rows.Add(table.Rows.Count + 1, name); } } }
هر زمان که رویداد page load انجام میشود؛ بررسی میکند که آیا postback صورت گرفته یا نه. بسته به نتیجه ،باید با وارد شدن داده برای اولین بار و یا افزودن یک رکورد جدید به مجموعه صورت بگیرد. رکورد Name value به عنوان آرگومان رویداد هنگامی که در حال اجرای __doPostBack از کلاینت جاوا اسکریپت باشد ،ارسال میشود. مقدار آرگومان را در سمت سرور نگه میدارد و پس از آن برای اضافه شدن به رکورد جدید مورد استفاده قرار میدهد.
در این مثال با نوشتن نام و کلیک بروی لینک "افزودن "، خواهید دید که یک نام جدید به grid اضافه میشود.
کنترل Grid View تودرتو
در این مثال ،ما یک جفت کنترل grid داریم که براساس هر ورودی رویداد را بروزرسانی میکند. لیست کشویی شامل نام کشورها و دو کنترل grid ،شامل استان و شهر وجود دارند .کد این مثال پیچیده تر از مثال قبلی است ، در اینجا برای رویدادهای صفحه از Asp.Net ajax استفاده میکنیم.دو راه برای بروزرسانی grid ها وجود دارد
1. به روزرسانی grid زمانی که ورودی تغییر میکند.
2. به روز رسانی grid دوم براساس تعامل کاربر با گرید اول
در این مثال با استفاده از تست داده های جدول در کد ، داده های استاتیک را ایجاد میکند.
یک صفحه وب فرم جدید بنام MultipleGrids.aspx ایجاد کرده .و یک drop down بنام cboCountryList که شامل لیست کشورها میباشد ،اضافه میکنیم. زمانی که مقدار در ورودی تغییر کرد ما نیاز به بروزرسانی grid داریم.لازم نیست drop down را به عنوان کنترل سرور داشته باشیم اما اگر شما میخواهید با کد سرور لیست را پر کنید،نیاز به ویژگی runat='server 'دارید.
دو کنترل Grid View از قسمت Update Panels برای بروزرسانی آسنکرون (غیر همزمان)،به صفحه اضافه میکنیم.در حال حاضر مشکلی که با ان مواجه هستیم این است که چگونه باید بروزرسانی آسنکرون را هندل کنیم.
برای به روز رسانی گریدهای تودرتو نیاز به اضافه کردن رویداد handler در لود صفحه Asp.Net Ajax داریم.
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded);
در بالا، تابع pageLoaded همیشه برای بارگذاری صفحه فراخوانی میشود. اینجا دقیقا همان جایی است که نیاز داریم کدهایی که refresh کردن محتویاتشان بعد از Update Panel تموم شده ، فراخوانی و اجرا شوند.
MultipleGrids.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MultipleGrids.aspx.cs" Inherits="WebApplication.MultipleGrids_aspx" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script src="https://code.jquery.com/jquery-1.12.0.min.js" type="text/javascript"></script> </head> <body dir="rtl"> <form id="Form1" runat="server" > <div style="padding: 50px" style="border-style:groove"> <asp:ScriptManager ID="scriptManager1" runat="server" AsyncPostBackTimeout="90"></asp:ScriptManager> <select ID="cboCountryList"> <option value="0" selected>ایالات متحده</option> <option value="1">ایران</option> </select> <h3> استان </h3> <asp:UpdatePanel ID="upMain1" runat="server" UpdateMode="Conditional" AutoGenerateColumns="false"> <ContentTemplate> <asp:GridView ID="gridMain1" runat="server" OnDataBinding="gridMain1_DataBinding" OnRowDataBound="gridMain1_RowBound" CellPadding="4" ForeColor="#333333" GridLines="None"> <AlternatingRowStyle BackColor="White" /> <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" /> <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" /> <RowStyle BackColor="#FFFBD6" ForeColor="#333333" /> <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" /> <SortedAscendingCellStyle BackColor="#FDF5AC" /> <SortedAscendingHeaderStyle BackColor="#4D0000" /> <SortedDescendingCellStyle BackColor="#FCF6C0" /> <SortedDescendingHeaderStyle BackColor="#820000" /> </asp:GridView> </ContentTemplate> </asp:UpdatePanel> <br /> <h3>شهرها</h3> <asp:UpdatePanel ID="upMain2" runat="server" UpdateMode="Conditional" AutoGenerateColumns="false"> <ContentTemplate> <asp:GridView ID="gridMain2" runat="server" OnDataBinding="gridMain2_DataBinding" CellPadding="4" ForeColor="#333333" GridLines="None"> <AlternatingRowStyle BackColor="White" /> <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" /> <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" /> <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" /> <RowStyle BackColor="#FFFBD6" ForeColor="#333333" /> <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" /> <SortedAscendingCellStyle BackColor="#FDF5AC" /> <SortedAscendingHeaderStyle BackColor="#4D0000" /> <SortedDescendingCellStyle BackColor="#FCF6C0" /> <SortedDescendingHeaderStyle BackColor="#820000" /> </asp:GridView> </ContentTemplate> </asp:UpdatePanel> </div> </form> <script> Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded); var upMain1ID = '<%= upMain1.ClientID%>'; var upMain2ID = '<%= upMain2.ClientID%>'; var gridMain1ID = '<%= gridMain1.ClientID%>'; var cboCountryList = null; document.addEventListener("DOMContentLoaded", onLoad); function onLoad() { cboCountryList = document.querySelector('#cboCountryList'); cboCountryList.addEventListener('change', UpdateCountry); loadGridMain1(); } function loadGridMain1() { $('#' + gridMain1ID).find('[gridmain1row="true"]').each(function (idx, el) { el.onclick = function () { var stateID = $(el).attr('StateID'); return function () { grid1RowClick(stateID); } }(); }); } function grid1RowClick(stateID) { __doPostBack(upMain2ID, stateID); } function pageLoaded(sender, args) { var prm = Sys.WebForms.PageRequestManager.getInstance(); if (prm.get_isInAsyncPostBack()) { // get our array of update panels that were updated during the request var updatedPanels = args.get_panelsUpdated(); for (var x = 0; x < updatedPanels.length; x++) { var panel = updatedPanels[x].id; switch (panel) { case upMain1ID: loadGridMain1(); __doPostBack(upMain2ID, ''); break; } } } } function UpdateCountry() { __doPostBack(upMain1ID, cboCountryList.value); return false; } </script> </body> </html>
وقتی مقدار در لیست کشویی تغییر میکند ، تمام grid ها یک به یک refresh میشود.همچنین وقتی در grid اول آیتمی را انتخاب میکنیم باید grid دوم refresh شود.با رویداد کلیک اتصال تغییر میکند ،بطوری که با فراخوانی تابع UpdateCountry با انتخاب کشور در لیست کشویی مقدار تغییر میکند و و زمانی که در ردیف گرید اول کلیک شود تابع grid1RowClick فراخوانی میشود. اتصال رویداد المنتهای HTML در داخل grid نیاز دارد درسمت سرور و کلاینت بکار گرفته شود. در سمت سرور ما باید ویژگی های سفارشی در رویداد Row Bound گرید اضافه کنیم .بعد وقتی صفحه در مرورگر بارگیری شد ما می توانیم المنتهای grid را بر اساس دسته ای از صفات شناسایی و در نتیجه المنت DOM را با توابع جاوا اسکریپت اتصال دهیم.
در grid اول استان کشور مورد نظر انتخاب میشود و در grid دوم شهرهای استانها انتخاب میشوند.در تابع pageLoaded از PageRequestManager.get_isInAsyncPostBack() برای بررسی اینکه آیا لود صفحه جاری جزئی است یا نه استفاده میشود. بر این اساس ما نیاز به identify کردن update panel برای ادامه chaining بلوک کد پس از refresh شدن داریم بنابراین، هنگامی که بارگذاری اولین update panel به پایان رسید، پس از آن __doPostBack را برای update panel گرید دوم فراخوانی میکنیم.
MultipleGrids.aspx.cs
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebApplication { public enum Countries { UnitedStates = 0, India = 1 } public partial class MultipleGrids_aspx : System.Web.UI.Page { private DataTable _stateTable; private DataTable _cityTable; /// <summary> /// Page load event /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { Session["SelectedCountry"] = 0; Session["SelectedState"] = 5; SetData(); } else { String target = Request["__EVENTTARGET"]; String parameter = Request["__EVENTARGUMENT"]; if (target == "upMain1") { Session["SelectedCountry"] = Convert.ToInt32(parameter); switch ((Countries)Session["SelectedCountry"]) { case Countries.UnitedStates: Session["SelectedState"] = 5; break; case Countries.India: Session["SelectedState"] = 1; break; } } else if (target == "upMain2" && parameter.Length > 0) { Session["SelectedState"] = Convert.ToInt32(parameter); } } gridMain1.DataBind(); gridMain2.DataBind(); } /// <summary> /// Grid data binding event /// </summary> /// <param name="e"></param> protected void gridMain1_DataBinding(object sender, EventArgs e) { (Session["StateTable"] as DataTable).DefaultView.RowFilter = String.Format("CountryID = '{0}'", (Int32)Session["SelectedCountry"]); gridMain1.DataSource = (Session["StateTable"] as DataTable).DefaultView; } /// <summary> /// Grid data binding event /// </summary> /// <param name="e"></param> protected void gridMain2_DataBinding(object sender, EventArgs e) { (Session["CityTable"] as DataTable).DefaultView.RowFilter = String.Format("StateID = '{0}'", (Int32)Session["SelectedState"]); gridMain2.DataSource = (Session["CityTable"] as DataTable).DefaultView; } /// <summary> /// Sets the initial data. /// </summary> private void SetData() { _stateTable = new DataTable(); _cityTable = new DataTable(); //State table _stateTable.Columns.Add("CountryID", typeof(Int32)); _stateTable.Columns.Add("StateID", typeof(Int32)); _stateTable.Columns.Add("استان", typeof(String)); _stateTable.Columns.Add("مساحت", typeof(String)); //City table _cityTable.Columns.Add("StateID", typeof(Int32)); _cityTable.Columns.Add("شهر", typeof(String)); _cityTable.Columns.Add("جمعیت", typeof(String)); #region Iran _stateTable.Rows.Add(1, 1, "تهران", "342,239"); _stateTable.Rows.Add(1, 2, "فارس", "400,362"); _stateTable.Rows.Add(1, 3, "اصفهان", "240,752"); _stateTable.Rows.Add(1, 4, "آذربایجان", "550,713"); _cityTable.Rows.Add(1, "تهران", "3,046,163"); _cityTable.Rows.Add(1, "ری", "1,138,300"); _cityTable.Rows.Add(1, "شمیرانات", "341,422"); _cityTable.Rows.Add(1, "ورامین", "307,713"); _cityTable.Rows.Add(2, "شیراز ", "1,618,879"); _cityTable.Rows.Add(2, "آباده", "1,183,549"); _cityTable.Rows.Add(2, "جهرم", "874,412"); _cityTable.Rows.Add(2, "فیروزآباد", "446,246"); _cityTable.Rows.Add(3, "اصفهان", "14,057,991"); _cityTable.Rows.Add(3, "کاشان", "1,243,414"); _cityTable.Rows.Add(3, "محلات", "705,579"); _cityTable.Rows.Add(3, "اصفهان", "580,990"); _cityTable.Rows.Add(4, "تبریز", "18,394,912"); _cityTable.Rows.Add(4, "ارومیه", "5,057,709"); _cityTable.Rows.Add(4, "سراب", "2,497,870"); _cityTable.Rows.Add(4, "میانه", "1,561,809"); #endregion Iran #region United States _stateTable.Rows.Add(0, 5, "Colorado", "268,602"); _stateTable.Rows.Add(0, 6, "Nevada", "284,422"); _stateTable.Rows.Add(0, 7, "Texas", "677,989"); _stateTable.Rows.Add(0, 8, "Montana", "376,944"); _cityTable.Rows.Add(5, "Denver", "663,862"); _cityTable.Rows.Add(5, "Colorado Springs", "445,830"); _cityTable.Rows.Add(5, "Aurora", "353,108"); _cityTable.Rows.Add(5, "Fort Collins", "156,480"); _cityTable.Rows.Add(6, "Las Vegas", "613,599"); _cityTable.Rows.Add(6, "Henderson", "277,440"); _cityTable.Rows.Add(6, "Reno", "236,995"); _cityTable.Rows.Add(6, "North Las Vegas", "230,788"); _cityTable.Rows.Add(7, "Houston", "2,239,558"); _cityTable.Rows.Add(7, "San Antonio", "1,436,697"); _cityTable.Rows.Add(7, "Dallas", "1,281,047"); _cityTable.Rows.Add(7, "Austin", "912,791"); _cityTable.Rows.Add(8, "Billings", "108,869"); _cityTable.Rows.Add(8, "Bozeman", "41,660"); _cityTable.Rows.Add(8, "Butte-Silver Bow", "33,980"); _cityTable.Rows.Add(8, "Great Falls", "59,152"); #endregion United States Session["StateTable"] = _stateTable; Session["CityTable"] = _cityTable; } /// <summary> /// Row bound event /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void gridMain1_RowBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { DataRowView row = e.Row.DataItem as DataRowView; e.Row.Attributes.Add("gridmain1row", "true"); e.Row.Attributes.Add("StateID", row["StateID"].ToString()); } } } }
کد بالا عمدتا کار همان مثال اول را انجام میدهد. به روز رسانی استان در gridهای ذخیره شده در application session state بر اساس رویداد آرگومان ها بروزرسانی میکنیم و پس از آن تست داده rebinds باgrid را انجام میدهیم .
رویداد gridMain1_RowBound برای افزودن ویژگیهای سفارشی gridmain1Row به هر ردیف grid استفاده میشود. آرگومان StateID نیز به عنوان یک ویژگی اضافه شده به طوری که در هر سطر می توانید اطلاعات استان خود را به تابع رویداد جاوا اسکریپت ارسال کنید. در کد های سمت کلاینت ، المنت سطرهایی که ویژگی gridmain1Row را دارند، از جی کوئری استفاده میشود و المنتهای خارج از حلقه را به بستار جاوا اسکریپت (JavaScript closure)اتصال میدهد.
برای تست ، کد کشور انتخاب شده را تغییر بدهید و خواهید دید که هر دو grid یکی پس از دیگری refresh میشود. در استان grid، روی استان مورد نظر کلیک کنید و میبینید که اطلاعات grid شهر refresh میشود.
- ASP.net
- 2k بازدید
- 6 تشکر