تذکر :
مخاطبين اين مقاله افراد متوسط و پيشرفته در زمينه ASP.NET در
نظر گرفته شده اند و آشنايي قبلي با کنترل هاي ASP.NET لازم مي باشد.
در ASP.NET 3.5 سه کنترل داده (Data Control) جديد اضافه شده
اند که عبارتند از ListView و DataPager و LinqDataSource.
ListView در حقيقت از نسل جديد کنترل هاي داده مي باشد که در
ASP.NET 3.5 ظهور پيدا کرده است و داراي انعطاف پذيري زيادي نسبت به کنترل هاي داده
کلاسيک از قبيل GridView و Repeater و DataList مي باشد.
به طور مثال در مقايسه با GridView بايد گفت که يکي از محدوديت
هاي GridView اين بود که اين کنترل يک مجموعه رکورد را در يک ساختار جدولي نشان مي
دهد و حتي اگر شما در GridView از TemplateField استفاده کنيد، باز هم GridView پس
از رندر کردن محتواي خود، Markup توليد شده را داخل تگ table توليد شده توسط خود،
قرار مي دهد ولي در ListView اينگونه نيست و انعطاف پذيري بيشتري نسبت به GridView
وجود دارد.
ListView هيچ گونه Markup اضافي توليد نمي کند و امکانات
بيشتري جهت نمايش رکورد ها به شکل هاي مختلف در اختيار ما قرار مي دهد.
Markup توليد شده توسط ListView مي تواند در 11 تمپليت ايجاد
شود که عبارتند از :
از ميان تمپليت هايي که در بالا ذکر شد، دو تمپليت LayoutTemplate و ItemTemplate
بايد حتما در ListView تعريف شوند و استفاده از بقيه تمپليت ها اختياري و وابسته به
امکاناتي است که در نظر داريم از آن ها استفاده کنيم.
براي شروع کار به مثال زير توجه فرماييد.
<asp:ListView
ID="ListView1"
runat="server"
DataSourceID="SqlDataSource1">
<LayoutTemplate>
<ol>
<asp:PlaceHolder
runat="server"
ID="itemPlaceholder"></asp:PlaceHolder>
</ol>
</LayoutTemplate>
<ItemTemplate>
<li>
<%# Eval("columnName")
%>
</li>
</ItemTemplate>
</asp:ListView>
|
همانطور که ملاحظه فرموديد ما در قطعه کد بالا از دو تمپليت LayoutTemplate و
ItemTemplate استفاده نموده ايم.
رکورد هايي را که قصد داريم توسط ListView نمايش داده شوند، در
ItemTemplate رندر مي شوند و سپس در محل مناسب خود، که توسط LayoutTemplate مشخص مي
شود قرار مي گيرند.
همانطور که در تگ LayoutTemplate مشاهده مي نماييد با از کنترل
PlaceHolder محل قرار گيري کدهاي Markup توليد شده در ItemTemplate را مشخص کرده
ايم. در حقيقت Markup توليد شده در قسمت ItemTemplate در اين مثال دقيقا بعد از تگ
<ol> و قبل از <ol/> قرار مي گيرند و Markup نهايي توليد مي شود.
قطعه کد بالا يک ليست ترتيبي از رکورد هايي که به ListView
بايند شده اند را نمايش مي دهد.
به طور مثال کدهاي Markup توليد شده در ItemTemplate مي تواند
به شکل زير باشد.
<li>Scott Mitchell</li> <li>Sam Smith</li> <li>Jisun Lee</li>
<li>Andrew Fuller</li> <li>Edgar Johnson</li> <li>Ellen Plank</li> |
و هنگامي که اين Markup در محل کنترل PlaceHolder قرار مي گيرد، Markup توليد شده
نهايي به صورت زير مي باشد.
<ol> <li>Scott Mitchell</li> <li>Sam
Smith</li> <li>Jisun Lee</li> <li>Andrew Fuller</li> <li>Edgar
Johnson</li> <li>Ellen Plank</li> </ol> |
نکته بسيار مهم :
1 . همانند ساير کنترل هاي سمت سرور، کنترل PlaceHolder نيز
داراي صفت ID مي باشد. ID اين کنترل به طور پيشفرض بايد itemPlaceHolder باشد
و در غير اينصورت هنگام اجراي برنامه خطايي ايجاد مي شود. پس يادتان باشد که نام
اين PlaceHolder حتما بايد itemPlaceHolder باشد. البته اين نام را مي توان
تغيير داد ولي در اين صورت بايد به طور صريح توسط ListView نام آن مشخص گردد. در
ادامه اين مقاله اين عمل را انجام خواهم داد.
2. استفاده از کنترل PlaceHolder يکي از راه هاي موجود جهت
معرفي محل قرارگيري کدهاي Markup ايجاد شده در تمپليت ItemTemplate مي باشد و راه
جايگزين ديگري نيز وجود دارد. کافيست تگي را که قرار است کدهاي Markup در آن قرار
بگيرند (در اينجا <ol>) تغييراتي دهيم.
بايد مانند کنترل PlaceHolder مقدار ID اين کنترل را
itemPlaceHolder و نيز صفت runat=server را نيز به آن اضافه کنيم. دقت شود که
الزام تمامي تگ هاHTML با اين موضوع سازگار نيستند و بايد هنگام استفاده از اين
قابليت به اين موضوع توجه داشت. (تگ هاي tr و td سازگاري خوبي دارند)
در قطعه کد زير از روش جايگزين استفاده شده است و عملکرد آن
دقيقا شبيه قطعه کد بالا است.
<asp:ListView
ID="ListView1"
runat="server"
DataSourceID="SqlDataSource1">
<LayoutTemplate>
<ol
runat="server"
id="itemPlaceholder">
</ol>
</LayoutTemplate>
<ItemTemplate>
<li>
<%# Eval("columnName")
%>
</li>
</ItemTemplate>
</asp:ListView>
|
همانطور که ملاحظه مي نماييد ديگر از کنترل PlaceHolder استفاده نشده است.
عملکرد تمپليت هاي AlternatingItemTemplate و
ItemSeparatorTemplate و EmptyDataTemplate همانند کنترل هاي داده کلاسيک مي باشد.
به مثال ديگرتوجه کنيد.
<asp:ListView
ID="ProductDataList2"
runat="server"
DataSourceID="SqlDataSource"
GroupItemCount="3">
<LayoutTemplate>
<table>
<tr>
<td>
<table
border="0"
cellpadding="5">
<asp:PlaceHolder
runat="server"
ID="groupPlaceHolder"></asp:PlaceHolder>
</table>
</td>
</tr>
</table>
</LayoutTemplate>
<GroupTemplate>
<tr>
<asp:PlaceHolder
runat="server"
ID="itemPlaceHolder"></asp:PlaceHolder>
</tr>
</GroupTemplate>
<ItemTemplate>
<td>
<h2>
<%# Eval("ProductName")
%>
</h2>
Price:
<%#Eval("UnitPrice",
"{0:c}")%>
<br
/>
Category:
<%# Eval("CategoryName")
%>
</td>
</ItemTemplate>
</asp:ListView>
|
ListView در مثال بالا رکورد ها را با ساختار جدولي نشان مي دهد.
گروه بندي اطلاعات در ListView :
کنترل ListView امکان نمايش رکورد ها به شکل گروهي را مي دهد.
مثلا فرض کنيد شما تعدادي رکورد داريد که قصد داريد آن ها را در گروه هاي 3 تايي
نمايش دهيد.
به مثال زير توجه فرماييد.
<asp:ListView
ID="ProductList1"
runat="server"
DataSourceID="ProductDataSource"
GroupItemCount="3"
ItemPlaceholderID="itemsGoHere"
GroupPlaceholderID="groupsGoHere">
<LayoutTemplate>
<p>
<asp:PlaceHolder
runat="server"
ID="groupsGoHere"></asp:PlaceHolder>
</p>
</LayoutTemplate>
<GroupTemplate>
<ol>
<asp:PlaceHolder
runat="server"
ID="itemsGoHere"></asp:PlaceHolder>
</ol>
</GroupTemplate>
<ItemTemplate>
<li>
<%#Eval("ProductName")%>
</li>
</ItemTemplate>
</asp:ListView>
|
قبل از اينکه به تشريح عملکرد قطعه کد فوق بپردازم، نظر شما را به تذکر زير جلب
مي کنم.
تذکر :
همانطور که قبلا اشاره شد، ASP.NET 3.5 به طور پيش فرض نامي را
که براي صفت ID کنترل PlaceHolder در نظر مي گيرد، itemPlaceHolder مي
باشد. در GroupTemplate نيز يک PlaceHolder قرار مي گيرد که نام پيش فرضي که به آن
نسبت داده مي شود عبارت است از groupPlaceHolder.
ولي همانطور در قطعه کد بالا ملاحظه مي کنيد، ما نام اين کنترل
را تغيير داده ايم. به طوريکه که در تگ ListView به صورت bold مشخص شده است،
مشاهده مي کنيد که از دو صفت جديد ListView جهت مشخص نمودن نام هاي مورد نظر خود،
جهت PlaceHolder ها استفاده نموده ايم.
ItemPlaceHolderID نام مورد نظر خود را که قصد داريم به
PlaceHolder ي که در GroupTemplate قرار مي گيرد، نگهداري مي کند(در اينجا
itemsGoHere مي باشد)
و صفت GroupPlaceHolderID نام مورد نظر خود را که قصد داريم
به PlaceHolder ي که در LayoutTemplate قرار مي گيرد نگهداري مي کند( در
اينجا groupsGoHere مي باشد)
صفت GroupItemCount، تعداد اعضايي را که قصد داريم در يک گروه
قرار بگيرند را مشخص مي کند.
اکنون به تشريح عملکرد قطعه کد فوق مي پردازم.
به ListView در مثال بالا يک تمپليت جديد به نام GroupTemplate
اضافه شده است که جهت نمايش رکوردها با شکل گروهي استفاده مي شود.
عملکرد ListView به اين شکل مي باشد که ابتدا تمپليت
ItemTemplate به تعداد دفعاتي که مشخص کرده ايم (توسط صفتGroupItemCount ) تکرار مي
شود و Markup آن توليد مي شود. سپس اين Markup در محل PlaceHolder ي که در
GroupTemplate قرار دارد، قرار مي گيرد و Markup نهايي آن توليد مي شود. و اين چرخه
تا زماني که تمام رکورها رندر شوند، ادامه پيدا خواهد کرد.
در نهايت، Markup توليد شده نهايي توسط تمپليت هايItemTemplate
و GroupTemplate در LayoutTemplate قرار مي گيرد و کار به اتمام مي رسد.
براي فراگيري بهتر مسئله، به Markup نهايي توليد شده، توسط
ListView بالا توجه فرماييد.
<p> <ol>
<li>Scott Mitchell</li> <li>Sam Smith</li> <li>Jisun Lee</li>
</ol> <ol> <li>Andrew Fuller</li>
<li>Edgar Johnson</li> <li>Ellen Plank</li> </ol>
<ol> <li>Tito Wald</li> <li>Layla
Clapton</li>
</ol>
</p> |
توجه داشته باشيد که
- تگ هاي <p> و <p/> در
LayoutTemplate توليد شده اند
- تگ هاي <ol> و <ol/>
درGroupTemplate توليد شده اند
- تگ هاي <li> و <li/>
در ItemTemplate توليد شده اند
نمايش اطلاعات به صورت چند ستوني (Multi-Column):
يکي از نيازهايي که يک برنامه نويس معمولا با آن مواجه مي شود،
نمايش رکورد ها در چند ستون مي باشد.
فرض کنيد که قصد داريد نام و نام خانوادگي و عکس تعدادي از
کارمندان را در يک صفحه نمايش دهيد. اگر تمام رکورد ها را به طور معمولي و زير هم
نشان دهيد، نتيجه نهايي چندان جالب نمي باشد ولي اگر اطلاعات هر 5 کارمند را در يک
سطر نمايش دهيد، شکل زيباتري پيدا خواهد کرد.
يادآوري :
نمايش اطلاعات به صورت چند ستوني را قبلا معمولا توسط کنترل
DataList و با استفاده از صفات RepeatColumns و RepeatDirection انجام مي داديم. با
استفاده از اين روش Markup زيادي به طور اجباري توليد مي شود که هرگز بهينه نيست.
ولي با استفاده از ListView اين عمل به شکل بسيار جالبي انجام خواهد شد.
فرض کنيد که قرار است نام و قيمت و دسته بندي تعدادي محصول را
نمايش دهيد به طوريکه در هر سطر، مشخصات سه محصول نمايش داده شود.
به قطعه کد زير توجه فرماييد.
<asp:ListView
ID="ProductDataList2"
runat="server"
DataSourceID="SqlDataSource1"
GroupItemCount="3">
<LayoutTemplate>
<table>
<tr>
<td>
<table
border="0"
cellpadding="5">
<asp:PlaceHolder
runat="server"
ID="groupPlaceHolder"></asp:PlaceHolder>
</table>
</td>
</tr>
</table>
</LayoutTemplate>
<GroupTemplate>
<tr>
<asp:PlaceHolder
runat="server"
ID="itemPlaceHolder"></asp:PlaceHolder>
</tr>
</GroupTemplate>
<ItemTemplate>
<td>
<h2>
<%# Eval("ProductName")
%>
</h2>
Price:
<%#Eval("UnitPrice",
"{0:c}")%>
<br
/>
Category:
<%# Eval("CategoryName")
%>
</td>
</ItemTemplate>
</asp:ListView>
|
عملکرد قطعه کد فوق کاملا واضح مي باشد.
در LayoutTemplate دو table تعريف شده است که table خارجي در
بر گيرنده table داخلي مي باشد و نقش خاصي را ايفا نمي کند.
تمپليت ItemTemplate مرتبا اطلاعات مربوط به 3 رکورد را رندر
نموده و Markup توليد شده توسط هريک رکورد را در يک تگ<td> قرار مي دهد و سپس اين
سه عدد <td> توليد شده، در GroupTemplate که حاوي تگ <tr> مي باشد، قرار مي گيرند.
پس هر سه عدد تگ <td> داخل يک عدد تگ <tr> قرار مي گيرند.
اين عمل تا پايان رندر شدن تمامي رکورد ها تکرار مي شود و در
نهايت Markup نهايي شامل مجموعه اي از <tr> ها مي شود و در پايان اين <tr> ها
در محل مناسب خود در LayoutTemplate قرار مي گيرند و Markup نهايي توليد مي
شود.
شکل زير عملکرد قطعه کد فوق را نمايش مي دهد.
خوب، تا اينجا اطلاعات را به صورت چند ستوني نمايش داده ايم. اکنون فرض کنيد تعداد
محصولات ما 13 عدد است و در نتيجه اگر بخواهيم اطلاعات را به صورت 3 ستوني نشان
دهيم با چه وضعيتي روبرو خواهيم شد؟!
در سطر آخر فقط يک محصول باقي مي ماند!
براي رفع اين مشکل از تمپليت EmptyItemTemplate استفاده
مي شود. اين تمپليت، Markup پيشفرضي را که قصد داريم در ستون هايي که خالي مانده
اند، نمايش دهيم را نگهداري نمايد.
به قطعه کد زير که تغيير يافته قطعه کد فوق است توجه فرماييد.
<asp:ListView
ID="ListView2"
runat="server"
DataSourceID="SqlDataSource1"
GroupItemCount="3">
<LayoutTemplate>
<table>
<tr>
<td>
<table
border="0"
cellpadding="5">
<asp:PlaceHolder
runat="server"
ID="groupPlaceHolder"></asp:PlaceHolder>
</table>
</td>
</tr>
</table>
</LayoutTemplate>
<GroupTemplate>
<tr>
<asp:PlaceHolder
runat="server"
ID="itemPlaceHolder"></asp:PlaceHolder>
</tr>
</GroupTemplate>
<ItemTemplate>
<td>
<h2>
<%# Eval("ProductName")
%></h2>
Price:
<%#Eval("UnitPrice",
"{0:c}")%><br
/>
Category:
<%# Eval("CategoryName")
%>
</td>
</ItemTemplate>
<EmptyItemTemplate>
Coming Soon New Product (30sharp.com)!
</EmptyItemTemplate>
</asp:ListView>
|
معرفي کنترل DataPager :
کنترل ListView داراي قابليت Paging در درون خود نمي باشد و
براي انجام عمل Paging به آن بايد از کنترل DataPager استفاده نمود.
برخلاف کنترل هاي داده کلاسيک مانند GridView که داراي قابليت
Paging در درون خود بودند و Paging را در قسمت پايين خود نمايش مي دادند، کنترل
DataPager را مي توان در هر نقطه اي از صفحه به کار برد و در نتيجه قسمت Paging را
مي توان در هر محل دلخواهي نمايش داد.
همانطور که در قبلا در
مقاله اي اشاره شد، کنترل DataPager را در حال حاضر تنها با کنترل
ListView مي توان به کار برد.
به مثال زير توجه فرماييد.
<asp:ListView
ID="ListView3"
runat="server"
DataSourceID="ProductDataSource">
<LayoutTemplate>
<table>
<asp:PlaceHolder
runat="server"
ID="itemPlaceholder"
/>
</table>
<asp:DataPager
ID="dp1"
runat="server"
PageSize="10">
<Fields>
<asp:NumericPagerField
/>
</Fields>
</asp:DataPager>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
<%#Eval("CountryName")%>
</td>
<td>
<%#Eval("CapitalCity")%>
</td>
</tr>
</ItemTemplate>
</asp:ListView>
|
همانطور که مشاهده مي شود، در اين مثال DataPager در قسمت LayoutTemplate و پايين
تر از PlaceHolder قرار گرفته است. پس هنگام اجراي برنامه مشاهده مي شود که قسمت
Paging در پايين ListView نمايش داده مي شود.
کنترل ListView بالا هنگام اجراي برنامه شبيه به شکل زير خواهد
بود.
تگ DataPager داراي صفات زيادي مي باشد. يکي از مهمترين اين صفات PageSize مي باشد.
اين صفت مشخص مي کند که درهر صفحه چند رکورد ميتواند نمايش داده شود.
داخل DataPager بعد از تگ Field بايد نحوه نمايش Paging را
مشخص کنيم.
داخل تگ Field مي توان 3 نوع نمايش را براي Paging انتخاب کرد
که عبارتند از :
- NextPreviousPagerField : با انتخاب اين روش دکمه هاي
Next و Previous جهت انجام عمل Paging
استفاده مي شود. اين تگ داراي صفات ديگري نيز مي باشد که مي توان قسمت
Paging را سفارشي تر کرد. مثلا متن دکمه ها را تغيير داد يا عکسي
براي آن ها انتخاب نمود يا نوع دکمه ها تغيير داد و غيره
- NumericPagerField : با انتخاب اين روش دکمه هاي Paging
به صورت عددي (....3و2و1) نمايش داده مي شوند. صفت ButtonCount
، تعداد دکمه هايي را که قصد داريم در صفحه جهت اعمال عمل Paging
نمايش داده شود را مشخص مي کند. در اين روش هم صفات زيادي جهت سفارشي سازي نحوه
نمايش Paging وجود دارد.
- TemplatePagerField : با انتخاب اين روش مي توان به طور کامل
قسمت Paging را سفارشي کرد و نسبت به دو روش قبل نياز به کار
بيشتري دارد. با استفاده از رويداد OnPagerCommand مي توانيد نحوه عملکرد قسمت
Paging را مديريت کنيد. براي اطلاعات بيشتر در مورد اين روش مي
توانيد به
اينجا مراجه کنيد.
در مثال بالا ما از NumericPagerField استفاده نموده ايم.
اکنون به قطعه کد زير توجه فرماييد.
<asp:ListView
ID="ListView4"
DataSourceID="SqlDataSource1"
runat="server">
<LayoutTemplate>
<asp:DataPager
runat="server"
ID="ItemDataPager"
PageSize="5">
<Fields>
<asp:NextPreviousPagerField
/>
</Fields>
</asp:DataPager>
<table
border="1"
width="300"
cellpadding="5">
<tr
id="Tr1"
runat="server"
style="background-color:
#CCCCCC;">
<th
id="Th1"
runat="server"
align="left">
Country Name
</th>
<th
id="Th2"
runat="server"
align="left">
Capital City
</th>
</tr>
<tr
id="ItemPlaceHolder"
runat="server">
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr
id="Tr2"
runat="server">
<td
align="left">
<asp:Label
ID="CountryName"
runat="server"><%#Eval("CountryName")%></asp:Label>
</td>
<td
align="left">
<asp:Label
ID="CapitalCity"
runat="server"><%#Eval("CapitalCity")%></asp:Label>
</td>
</tr>
</ItemTemplate>
</asp:ListView>
|
تفاوت اين قطعه کد با قطعه کد قبلي در اين است که اولا DataPager به قبل از محل
PlaceHolder منتقل شده است وثانيا نوع Paging را NextPreviousPagerField انتخاب
نموده ايم.
قرار دادن DataPager خارج از ListView :
همانطور که قبلا ذکر کردم، DataPager را مي توان در هر جايي از
صفحه قرار داد و در نتيجه قسمت Paging را مي توان در هر جايي از صفحه قرار داد.
به قطعه کد زير توجه فرماييد.
<asp:DataPager
runat="server"
ID="ItemDataPager"
PageSize="5"
PagedControlID="ListView1">
<Fields>
<asp:NextPreviousPagerField
/>
</Fields>
</asp:DataPager>
<br
/>
<strong>ListView
- DataPager - 30sharp.com</strong>
<br
/>
<br
/>
<asp:ListView
ID="ListView1"
DataSourceID="SqlDataSource1"
runat="server">
<LayoutTemplate>
<table
border="1"
width="300"
cellpadding="5">
<tr
id="Tr1"
runat="server"
style="background-color:
#CCCCCC;">
<th
id="Th1"
runat="server"
align="left">
Country Name
</th>
<th
id="Th2"
runat="server"
align="left">
Capital City
</th>
</tr>
<tr
id="ItemPlaceHolder"
runat="server">
</tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr
id="Tr2"
runat="server">
<td
align="left">
<asp:Label
ID="CountryName"
runat="server"><%#Eval("CountryName")%></asp:Label>
</td>
<td
align="left">
<asp:Label
ID="CapitalCity"
runat="server"><%#Eval("CapitalCity")%></asp:Label>
</td>
</tr>
</ItemTemplate>
</asp:ListView>
|
همانطور که ملاحظه مي کنيد، صفت PagedControlID در DataPager نام کنترلي که قرار
است Paging براي آن اعمال شود را نگهداري مي کند(در اينجا ListView1 )
شکل حاصل از ListView فوق به صورت زير مي باشد.
چندين مثال در مورد ListView از لينک بالاي صفحه قابل دريافت
مي باشد.
منابع :
موفق باشيد