انجمن‌های فارس وب

نسخه کامل: معرفی کنترل های ListView و DataPager در ASP.NET 3.5
شما در حال بازدید از بایگانی ارسال های انجمن هستید این نسخه کامل نیست : برای مشاهده نسخه کامل اینجا کلیک کنید
در 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 تمپليت ايجاد شود که عبارتند از :


  1. [ جهت مشاهده لينك عضو شويد ! ]
  2. [ جهت مشاهده لينك عضو شويد ! ]
  3. [ جهت مشاهده لينك عضو شويد ! ]
  4. [ جهت مشاهده لينك عضو شويد ! ]
  5. [ جهت مشاهده لينك عضو شويد ! ]
  6. [ جهت مشاهده لينك عضو شويد ! ]
  7. [ جهت مشاهده لينك عضو شويد ! ]
  8. [ جهت مشاهده لينك عضو شويد ! ]
  9. [ جهت مشاهده لينك عضو شويد ! ]
  10. [ جهت مشاهده لينك عضو شويد ! ]
  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 فوق به صورت زير مي باشد.






منابع :

4guysfromrolla
basgun
MSDN
Apress - Pro ASP.NET 3.5 in C# 2008, Second Edition
[ جهت مشاهده لينك عضو شويد ! ]

با سلام و تشکر

متاسفانه برای من صفحه بندی اش کار نمی کنه ؟؟؟
یک datapager که می ذارم ، صفحات بعدی را درست نشان نمی دهد؟؟؟
ایا نکته دیگری وجود دارد؟؟؟
مرجع آدرس ها