سفارشی کردن صفحه بندی WebGrid در ASP.NET MVC
پنج شنبه 28 آبان 1394 8:06 AM
بعد از استفاده از گریدهای Grid.mvc , JQGrid, Kendo و مشکلاتی که با هر کدام از آنها داشتم، در نهایت به WebGrid که به صورت توکار وجود دارد، برای استفاده جهت نمایش اطلاعات رسیدم؛ از این جهت که به کتابخانهی جانبی نیازی ندارد و از نظر سرعت و لود شدن بهینه میباشد، البته با اضافه کردن یکسری کدهای css.
برای آشنایی بیشتر با این helper توصیه میکنم ابتدا این مقاله را مطالعه نمایید.
به صورت پیش فرش WbebGrid صفحه بندی را به صورت خیلی ساده فقط با نمایش اعداد و جهت نماهای جلو و عقب، نشان میدهد که برای پروژههای رسمی تا حدودی جالب نیست.
در این مطلب قصد داریم از کتابخانهی bootstrap جهت صفحه بندی استفاده کنیم و در نهایت به صفحه بندی زیر برسیم:
برای اینکار، ابتدا قبل از هر چیزی به یک متد الحاقی برای انجام صفحه بندی سفارشی سازی شده، نیاز داریم که کدهای این متد به صورت زیر خواهد بود:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
public static class WebGridExtensions { public static HelperResult PagerList( this WebGrid webGrid, WebGridPagerModes mode = WebGridPagerModes.NextPrevious | WebGridPagerModes.Numeric, string firstText = null , string previousText = null , string nextText = null , string lastText = null , int numericLinksCount = 5) { return PagerList(webGrid, mode, firstText, previousText, nextText, lastText, numericLinksCount, explicitlyCalled: true ); } private static HelperResult PagerList( WebGrid webGrid, WebGridPagerModes mode, string firstText, string previousText, string nextText, string lastText, int numericLinksCount, bool explicitlyCalled) { int currentPage = webGrid.PageIndex; int totalPages = webGrid.PageCount; int lastPage = totalPages - 1; var ul = new TagBuilder( "ul" ); var li = new List<TagBuilder>(); if (ModeEnabled(mode, WebGridPagerModes.FirstLast)) { if (String.IsNullOrEmpty(firstText)) { firstText = "اولین" ; } var part = new TagBuilder( "li" ) { InnerHtml = GridLink(webGrid, webGrid.GetPageUrl(0), firstText) }; if (currentPage == 0) { part.MergeAttribute( "class" , "disabled" ); } li.Add(part); } if (ModeEnabled(mode, WebGridPagerModes.NextPrevious)) { if (String.IsNullOrEmpty(previousText)) { previousText = "قبلی" ; } int page = currentPage == 0 ? 0: currentPage - 1; var part = new TagBuilder( "li" ) { InnerHtml = GridLink(webGrid, webGrid.GetPageUrl(page), previousText) }; if (currentPage == 0) { part.MergeAttribute( "class" , "disabled" ); } li.Add(part); } if (ModeEnabled(mode, WebGridPagerModes.Numeric) && (totalPages > 1)) { int last = currentPage + (numericLinksCount / 2); int first = last - numericLinksCount + 1; if (last > lastPage) { first -= last - lastPage; last = lastPage; } if (first < 0) { last = Math.Min(last + (0 - first), lastPage); first = 0; } for ( int i = first; i <= last; i++) { var pageText = (i + 1).ToString(CultureInfo.InvariantCulture); var part = new TagBuilder( "li" ) { InnerHtml = GridLink(webGrid, webGrid.GetPageUrl(i), pageText) }; if (i == currentPage) { part.MergeAttribute( "class" , "active" ); } li.Add(part); } } if (ModeEnabled(mode, WebGridPagerModes.NextPrevious)) { if (String.IsNullOrEmpty(nextText)) { nextText = "بعدی" ; } int page = currentPage == lastPage ? lastPage: currentPage + 1; var part = new TagBuilder( "li" ) { InnerHtml = GridLink(webGrid, webGrid.GetPageUrl(page), nextText) }; if (currentPage == lastPage) { part.MergeAttribute( "class" , "disabled" ); } li.Add(part); } if (ModeEnabled(mode, WebGridPagerModes.FirstLast)) { if (String.IsNullOrEmpty(lastText)) { lastText = "آخرین" ; } var part = new TagBuilder( "li" ) { InnerHtml = GridLink(webGrid, webGrid.GetPageUrl(lastPage), lastText) }; if (currentPage == lastPage) { part.MergeAttribute( "class" , "disabled" ); } li.Add(part); } ul.InnerHtml = string .Join( "" , li); var html = "" ; if (explicitlyCalled && webGrid.IsAjaxEnabled) { var span = new TagBuilder( "span" ); span.MergeAttribute( "data-swhgajax" , "true" ); span.MergeAttribute( "data-swhgcontainer" , webGrid.AjaxUpdateContainerId); span.MergeAttribute( "data-swhgcallback" , webGrid.AjaxUpdateCallback); span.InnerHtml = ul.ToString(); html = span.ToString(); } else { html = ul.ToString(); } return new HelperResult(writer => { writer.Write(html); }); } private static String GridLink(WebGrid webGrid, string url, string text) { TagBuilder builder = new TagBuilder( "a" ); builder.SetInnerText(text); builder.MergeAttribute( "href" , url); if (webGrid.IsAjaxEnabled) { builder.MergeAttribute( "data-swhglnk" , "true" ); } return builder.ToString(TagRenderMode.Normal); } private static bool ModeEnabled(WebGridPagerModes mode, WebGridPagerModes modeCheck) { return (mode & modeCheck) == modeCheck; } } |
کلاس فوق باید در پوشهی App_Code قرار گیرد.
پس از آن در View یی که اطلاعات را نمایش میدهید، فقط لازم است کد زیر را اضافه نمایید:
1
2
3
|
<div> @grid.PagerList(mode: WebGridPagerModes.All) </div> |
تا اینجا متد مورد نظر برای انجام صفحه بندی گرید پیاده سازی شد. ادامهی کار هم مشخص است؛ داشتن یک PartialView جهت نمایش لیست اطلاعات، پاس دادن دیتا به Partial و تمام.
در ادامه برای تکمیل بحث مثالی را از نحوهی نمایش اطلاعات و صفحه بندی سفارشی نشان خواهیم داد:
PartialView لازم برای نمایش اطلاعات
تنظیمات لازم گرید :
1
2
3
4
5
6
7
|
@{ WebGrid grid = new WebGrid(Model, rowsPerPage: 10, ajaxUpdateContainerId: "grid" ); var rowIndex = ((grid.PageIndex + 1) * grid.RowsPerPage) - (grid.RowsPerPage - 1); } |
تعیین فیلدهای گرید :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@grid.Table( tableStyle: "table table-striped table-hover" , headerStyle: "webgrid-header" , alternatingRowStyle: "webgrid-alternating-row" , selectedRowStyle: "webgrid-selected-row" , rowStyle: "webgrid-row-style" , columns: grid.Columns( grid.Column(columnName: "Name" , header: "نام استان" , style: "myfont" ), grid.Column(columnName: "NameEn" , header: "نام استان ( انگلیسی )" , style: "myfont" ), grid.Column(header: "" , format: item => @Html.ActionLink( "مدیریت شهرها" , actionName: MVC.Admin.City.ActionNames.Index, controllerName: MVC.Admin.City.Name, routeValues: new {Code=item.Code },htmlAttributes: null )), grid.Column(header: "" , style: "text-align-center-col smallcell" , format: item => @Html.ActionLink(linkText: "ویرایش" , actionName: "Edit" , controllerName: "Province" , routeValues: new { area = "Admin" , code = item.Code }, htmlAttributes: new { @ class = "btn-sm btn-info vertical-center" })) ) ) <div> @grid.PagerList(mode: WebGridPagerModes.All) </div> |
خروجی حاصل به صورت زیر خواهد بود :
اگر طبق توضیحات بالا عمل کرده باشید، در نهایت صفحه بندی شما به صورت عمودی نمایش داده میشود؛ یعنی هر کدام از شماره صفحات در یک سطر. دلیل آن هم این است که تگ ul، کلاس .pagination را ندارد. در کدهای بوت استراپ تعریف شده است که تمام li هایی که به صورت مستقیم داخل کلاس .pagination هستند خصوصیات مورد نظر را بگیرند.
برای این کار دو راه حل وجود دارد :
راه حل اول: تغییر کدهای css
کدهای نوشته شده برای صفحه بندی در بوت استراپ را از حالت زیر:
1
|
.pagination > li |
به حالت زیر تغییر دهید:
1
|
.pagination li |
یادآوری : علامت < در CSS یعنی به صورت مستقیم و در شاخهی اول.
راه حل دوم - افزودن کلاس .pagination به تگ ul:
ابتدا کلاس .pagination را از تگ div حذف نمایید:
1
2
3
|
<div > @grid.PagerList(mode: WebGridPagerModes.All) </div> |
و در کدهایی کلاس WebGridExtensions، در قسمتی که تگ ul اصافه میشود، کلاس مورد نظر را به آن اضافه میکنیم:
1
2
|
var ul = new TagBuilder( "ul" ); ul.AddCssClass( "pagination" ); |
دانلود کدهای این مثال
نکتهای در مورد Webgrid
اگر نیاز داشتید به یکباره تمام اطلاعات را در گرید لود نکنید و به صورت n تاn تا رکوردها را نمایش دهید، در این حالت پس از پاس دادن لیستی از اطلاعات به View مورد نظر لازم است تعداد کل رکوردها را در یک متغییر به سمت View بفرستید. این کار به این دلیل میباشد که بتوان صفحه بندی را تولید کرد. برای این کار در بخش تنظیمات Webgrid مقدار source را برابر null قرار دهید و از قطعه کد زیر جهت بایند کردن گرید، بعد از کدهای تنظیمات WebGrid استفاده نمایید:
1
|
grid.Bind(Model, rowCount: ( int )ViewBag.PageCount); |