注:文字寫做是本人弱項,如描述有問題,請見諒!!!javascript
前言:在開發中,常常使用查詢分頁,爲了達到統一與複用,進行的統合實例,本實例將一步一步實現一個統合的查詢分頁的實現。html
開發工具:VS2012java
1.創建項目:
第一個是MVC4項目,第二個是一個類庫
2.在類庫PageSearchModel中添加引用以下:
3.要進行查詢,咱們添加一個查詢方法枚舉:QueryMethod.csgit
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace System.Web.Mvc { /// <summary> /// Html表單元素的檢索方式 /// </summary> public enum QueryMethod { /// <summary> /// 等於 /// </summary> //[GlobalCode("=", OnlyAttribute = true)] Equal = 0, /// <summary> /// 小於 /// </summary> //// [GlobalCode("<", OnlyAttribute = true)] LessThan = 1, /// <summary> /// 大於 /// </summary> // [GlobalCode(">", OnlyAttribute = true)] GreaterThan = 2, /// <summary> /// 小於等於 /// </summary> // [GlobalCode("<=", OnlyAttribute = true)] LessThanOrEqual = 3, /// <summary> /// 大於等於 /// </summary> // [GlobalCode(">=", OnlyAttribute = true)] GreaterThanOrEqual = 4, /// <summary> /// Like /// </summary> // [GlobalCode("like", OnlyAttribute = true)] Like = 6, /// <summary> /// In /// </summary> // [GlobalCode("in", OnlyAttribute = true)] In = 7, /// <summary> /// 輸入一個時間獲取當前天的時間塊操做, ToSql未實現,僅實現了IQueryable /// </summary> // [GlobalCode("between", OnlyAttribute = true)] DateBlock = 8, // [GlobalCode("<>", OnlyAttribute = true)] NotEqual = 9, // [GlobalCode("like", OnlyAttribute = true)] StartsWith = 10, // [GlobalCode("like", OnlyAttribute = true)] EndsWith = 11, /// <summary> /// 處理Like的問題 /// </summary> [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] Contains = 12, /// <summary> /// 處理In的問題 /// </summary> [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] StdIn = 13, /// <summary> /// 處理Datetime小於+23h59m59s999f的問題 /// </summary> [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] DateTimeLessThanOrEqual = 14 } }
4.添加一個排序類:QueryOrder.csajax
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace System.Web.Mvc { public class QueryOrder { public QueryOrder() { Order = OrderType.ASC; } /// <summary> /// 排序字段 /// </summary> public virtual string Field { get; set; } /// <summary> /// 排序方式 /// </summary> public virtual OrderType Order { get; set; } } public enum OrderType { ASC, DESC } }
5.添加一個組合查詢條件類:ConditionItem.csapp
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; namespace System.Web.Mvc { /// <summary> /// 用於存儲查詢條件的單元 /// </summary> public class ConditionItem { public ConditionItem() { } public ConditionItem(string field, QueryMethod method, object val) { Field = field; Method = method; Value = val; } /// <summary> /// 字段 /// </summary> public string Field { get; set; } /// <summary> /// 查詢方式,用於標記查詢方式HtmlName中使用[]進行標識 /// </summary> public QueryMethod Method { get; set; } /// <summary> /// 值 /// </summary> public object Value { get; set; } /// <summary> /// 前綴,用於標記做用域,HTMLName中使用()進行標識 /// </summary> public string Prefix { get; set; } /// <summary> /// 若是使用Or組合,則此組組合爲一個Or序列 /// </summary> public string OrGroup { get; set; } } }
6.添加一個表格的列類:PageColum.cside
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace System.Web.Mvc { /// <summary> /// 列 /// </summary> public class PageColum { public PageColum() { Id = Guid.NewGuid().ToString(); Sort = false; } /// <summary> /// 編號 /// </summary> public string Id { get; set; } /// <summary> /// 字段 /// </summary> public string Field { get; set; } /// <summary> /// 列頭名 /// </summary> public string Header { get; set; } /// <summary> /// 排序 DESC爲true /// </summary> public bool Sort { get; set; } /// <summary> /// 列樣式 /// </summary> public string Style { get; set; } } /// <summary> /// 列 /// </summary> public class PageColum<T> : PageColum { public Func<T, object> Format { get; set; } } }
7.添加一個表格的行類:PageRow.cs工具
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace System.Web.Mvc { /// <summary> /// 行 /// </summary> public class PageRow { public PageRow() { RowData = new List<RowItem>(); } // <summary> /// 行數據 /// </summary> public IList<RowItem> RowData { get; set; } /// <summary> /// 單行數據對象的主鍵字段名 /// </summary> public string SourcePrimaryKey { get; set; } /// <summary> /// 行樣式 /// </summary> public string Style { get; set; } } /// <summary> /// 行中單列數據 /// </summary> public class RowItem { /// <summary> /// 對應列編號 /// </summary> public string ColumId { get; set; } /// <summary> /// 是不是字段列 /// </summary> public bool CheckFieldColum { get; set; } /// <summary> /// 值 /// </summary> public object Vaule { get; set; } } }
8.添加一個查詢分頁類:PageModel.cs開發工具
using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Web; using System.Web.WebPages; namespace System.Web.Mvc { /// <summary> /// 分頁模型 /// </summary> public class PageModel { public PageModel() { this.PageIndex = 1; this.PageSize = 15; SearchQuery = new List<ConditionItem>(); Id = Guid.NewGuid().ToString().Replace(@"/","").Replace(@"\","").Replace("-", "_"); } /// <summary> /// 頁的惟一標識 /// </summary> public virtual string Id { get; set; } /// <summary> /// 頁碼從1開始 /// </summary> public virtual int PageIndex { get; set; } /// <summary> /// 每頁顯示數量 /// </summary> public virtual int PageSize { get; set; } /// <summary> /// 頁總數 /// </summary> public virtual long PageTotal { get { #region if (DataTotal == 0) { return 0; } else if (DataTotal <= PageSize) { return 1; } else { var z = DataTotal / PageSize; var y = DataTotal % PageSize; if (y != 0) { return z + 1; } else { return z; } } #endregion } } /// <summary> /// 數據總數 /// </summary> public virtual long DataTotal { get; set; } /// <summary> /// 查詢條件 /// </summary> public virtual List<ConditionItem> SearchQuery { get; set; } /// <summary> /// 排序 /// </summary> public virtual QueryOrder Order { get; set; } /// <summary> /// 是否全選 /// </summary> public bool SelectAll { get; set; } /// <summary> /// 選擇的查詢集合 /// </summary> public IList<string> SelectPrimaryKeys { get; set; } /// <summary> /// 判斷查詢字段是存在 /// </summary> /// <param name="expr"></param> /// <returns></returns> public bool CheckSearchName<T>(Expression<Func<T, object>> expr) { var field= expr.Body.ToString().Split('.').Last(); if (SearchQuery.Where(m => m.Field == field).Count() > 0) return true; else return false; } /// <summary> /// 查詢字段值 /// </summary> /// <param name="expr"></param> /// <returns></returns> public object SearchValue<T>(Expression<Func<T, object>> expr) { var field = expr.Body.ToString().Split('.').Last(); var data = this.SearchQuery.Where(m => m.Field == field); if (data.Count() > 0) { return data.First().Value; } return ""; } /// <summary> /// 設置當前分頁對象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="data"></param> /// <param name="dataTotal"></param> /// <returns></returns> public PageModel<T> Record<T>(IEnumerable<T> data, long dataTotal = -1) where T : class { var model = new PageModel<T>(data, dataTotal); model.PageIndex = this.PageIndex; model.PageSize = this.PageSize; model.Order = this.Order; model.SearchQuery = this.SearchQuery; return model; } } /// <summary> /// 分頁模型 /// </summary> public class PageModel<T> : PageModel,IHtmlString where T : class//,IHtmlString { public PageModel(IEnumerable<T> data, Int64 dataTotal = -1) : base() { #region 設置數據總數 if (data != null) DataSource = data; else DataSource = new List<T>(); if (dataTotal == -1) { if (data != null) { DataTotal = data.Count(); } else { DataTotal = 0; } } else { DataTotal = dataTotal; } #endregion this.TableClassName = "baseui-table"; Colums = new List<PageColum<T>>(); } /// <summary> /// 數據源 /// </summary> public virtual IEnumerable<T> DataSource { get; set; } /// <summary> /// 數據列 /// </summary> private IList<PageColum<T>> Colums { get; set; } /// <summary> /// 數據的主鍵字段名 /// </summary> private string SourcePrimaryKey { get; set; } /// <summary> /// 是否顯示選擇框 /// </summary> private bool ShowCheckBox { get; set; }//顯示選擇框 /// <summary> /// 列樣式類名 /// </summary> private string TableClassName { get; set; } /// <summary> /// 提交的表單ID /// </summary> private string SearchFormId { get; set; } /// <summary> /// 要查詢的form表單ID /// </summary> /// <param name="id"></param> /// <returns></returns> public PageModel<T> SetSearchFormId(string id) { this.SearchFormId = id; return this; } /// <summary> /// 是否顯示選擇框 /// </summary> /// <param name="show"></param> /// <returns></returns> public PageModel<T> SetShowCheckBox(bool show = false) { this.ShowCheckBox = show; return this; } /// <summary> /// 查詢字段 /// </summary> /// <param name="expr"></param> /// <returns></returns> public string SearchName(Expression<Func<T, object>> expr) { return expr.Body.ToString().Split('.').Last(); } /// <summary> /// 查詢字段值 /// </summary> /// <param name="expr"></param> /// <returns></returns> public object SearchValue(Expression<Func<T, object>> expr) { var data = this.SearchQuery.Where(m => m.Field == SearchName(expr)); if (data.Count() > 0) { return data.First().Value; } return ""; } /// <summary> /// 設置數據源的每一行的主鍵字段 /// </summary> /// <param name="expr"></param> /// <returns></returns> public PageModel<T> SetSourceKey(Expression<Func<T, object>> expr) { this.SourcePrimaryKey = expr.Body.ToString().Split('.').Last(); return this; } /// <summary> /// 設置表的樣式類 /// </summary> /// <param name="className"></param> /// <returns></returns> public PageModel<T> SetClass(string className) { this.TableClassName = className; return this; } /// <summary> /// 設置顯示列 /// </summary> /// <param name="expr"></param> /// <param name="header"></param> /// <param name="sort"></param> /// <param name="style"></param> /// <returns></returns> public PageModel<T> ColumFor(Expression<Func<T, object>> expr, string header = "", bool sort = false, string style = "") { var exprBody = expr.Body.ToString(); if (exprBody.Contains("Convert")) { exprBody = exprBody.Replace("Convert", "").Replace("(", "").Replace(")", ""); } var field = exprBody.Split('.').Last();//ExpressionHelper.GetExpressionText(expr); if (string.IsNullOrEmpty(header)) { try { var metadata = ModelMetadata.FromLambdaExpression<T, object>(expr, new ViewDataDictionary<T>()); string resolvedDisplayName = metadata.DisplayName ?? metadata.PropertyName ?? field.Split('.').Last(); header = HttpUtility.HtmlEncode(resolvedDisplayName); } catch//處理好比datetime類型的屬性 { try { //ModelMetadataProvider provider = ModelMetadataProviders.Current; //ModelMetadata containerMetadata = new ModelMetadata(provider, null, () => null, typeof(T), null); //var metadata = containerMetadata.Properties.FirstOrDefault(m => m.PropertyName == field); var metadata = GetModelMetadata<T>(field); string resolvedDisplayName = metadata.DisplayName ?? metadata.PropertyName ?? field.Split('.').Last(); header = HttpUtility.HtmlEncode(resolvedDisplayName); } catch { } } } this.Colums.Add(new PageColum<T>() { Field = field, Header = header, Style = style, Sort = sort }); return this; } /// <summary> /// 列 /// </summary> /// <param name="header"></param> /// <param name="func"></param> /// <param name="style"></param> /// <returns></returns> public PageModel<T> Colum(string header, Func<T, object> func, bool sort = false, string style = "") { this.Colums.Add(new PageColum<T>() { Field = "", Header = header, Style = style, Format = func, Sort = sort }); return this; } public MvcHtmlString ToMvcHtmlString() { var Model = this; var html = new StringBuilder(); if (Model.Order != null && Model.Order.Field != "") { html.Append(string.Format("<input name=\"[PageModel_Order]\" type=\"hidden\" value=\"{0}\">", Model.Order.Field + "|" + Model.Order.Order.ToString())); } else { html.Append(string.Format("<input name=\"[PageModel_Order]\" type=\"hidden\" value=\"{0}\">", "")); } html.Append(string.Format("<input name=\"[PageModel_PageIndex]\" type=\"hidden\" value=\"{0}\">", 1)); html.Append(string.Format("<input name=\"[PageModel_PageSize]\" type=\"hidden\" value=\"{0}\">", Model.PageSize.ToString())); html.Append(string.Format("<input name=\"[PageModel_CheckSearch]\" type=\"hidden\" value=\"{0}\">", "1")); html.Append(string.Format("<input name=\"[PageModel_SelectIds]\" type=\"hidden\" value=\"{0}\">", "")); html.Append(string.Format("<input name=\"[PageModel_PageTotal]\" type=\"hidden\" value=\"{0}\">", Model.PageTotal)); #region 表 var columCount = 0; html.Append(string.Format("<table class=\"{0}\">",this.TableClassName)); html.Append("<thead>"); html.Append("<tr>"); //html.Append("<th>[]</th>");//列頭 if (Colums != null) { columCount = Colums.Count; if (this.ShowCheckBox) { columCount += 1; html.Append("<th style=\"width: 40px;\" ><input class=\"baseui-checkbox\" onchange=\"PageModelCheck('pageModelCheck_All')\" id=\"pageModelCheck_All\" name=\"pageModelCheck_All\" type=\"checkbox\" value=\"true\">選擇</th>"); } foreach (var colum in Colums) { if (colum.Sort) { html.Append(string.Format("<th ><a href=\"javascript:;\" onclick=\"SearchPageModelOrder('{2}','{0}');\">{1}</a></th>" , colum.Field , colum.Header , this.SearchFormId)); } else { html.Append(string.Format("<th ><a href=\"javascript:;\">{0}</a></th>", colum.Header)); } } } html.Append("</tr>"); html.Append("</thead>"); html.Append("<tbody>"); if (Model != null && Model.DataSource.Count() > 0) { //html.Append("<td>[]</td>");//列 var rows = this.CreateRows(); foreach (var item in rows) { html.Append("<tr>"); if (this.ShowCheckBox) { html.Append(string.Format("<td><input class=\"baseui-checkbox\" onchange=\"PageModelCheck('pageModelCheck_{0}')\" id=\"pageModelCheck_{0}\" name=\"pageModelCheck_{0}\" type=\"checkbox\" value=\"true\"></td>", item.SourcePrimaryKey)); } foreach (var colum in item.RowData) { html.Append(string.Format("<td>{0}</td>", colum.Vaule)); } html.Append("</tr>"); } html.Append("</tbody>"); html.Append("<tfoot>"); html.Append("<tr>"); html.Append(string.Format("<td colspan=\"{0}\">", columCount)); html.Append("<div class=\"baseui-paging\">"); if (Model.PageIndex == 1) { html.Append(" <a href=\"javascript:;\" class=\"baseui-paging-prev\">"); html.Append("<i class=\"iconfont\" ></i> 第一頁"); html.Append("</a>"); } else { html.Append(string.Format(" <a href=\"javascript:;\" onclick=\"SearchPageModelPage('{0}','1');\" class=\"baseui-paging-prev\">", this.SearchFormId)); html.Append("<i class=\"iconfont\" ></i> 第一頁"); html.Append("</a>"); } var pNumber = 10; var start = GetStartNumber(Model.PageIndex, Model.PageTotal, pNumber); for (int i = 0; i < pNumber; i++) { if (start + i <= Model.PageTotal) { if (start + i == Model.PageIndex) { html.Append(string.Format("<a href=\"javascript:;\" class=\"baseui-paging-item baseui-paging-current\">{0}</a>", start + i)); } else { html.Append(string.Format("<a href=\"javascript:;\" onclick=\"SearchPageModelPage('{1}','{0}');\" class=\"baseui-paging-item\">{0}</a>", start + i, this.SearchFormId)); } } } if (Model.PageIndex == Model.PageTotal || Model.PageTotal == 0) { html.Append("<a href=\"javascript:;\" class=\"baseui-paging-next\">最後一頁 <i class=\"iconfont\" ></i></a>"); } else { html.Append(string.Format("<a href=\"javascript:;\" onclick=\"SearchPageModelPage('{1}','{0}');\" class=\"baseui-paging-next\">最後一頁 <i class=\"iconfont\"></i></a>", Model.PageTotal, this.SearchFormId)); } html.Append(string.Format("<span class=\"baseui-paging-info\"><span class=\"baseui-paging-bold\">{0}/{1}</span>頁</span>", Model.PageIndex, Model.PageTotal)); html.Append("<span class=\"baseui-paging-which\">"); html.Append(string.Format("<input name=\"[psome_name]\" value=\"{0}\" type=\"text\">", Model.PageIndex)); html.Append("</span>"); html.Append(string.Format(" <a class=\"baseui-paging-info baseui-paging-goto\" href=\"javascript:;\" onclick=\"SearchPageModelPageJmp('{0}')\">跳轉</a>", this.SearchFormId)); html.Append(" </div>"); html.Append(" </td>"); html.Append("</tr>"); html.Append("</tfoot>"); html.Append("</table>"); } else { html.Append("<tr>"); html.Append(string.Format("<td colspan=\"{0}\">暫無數據</td>", columCount)); html.Append("</tr>"); html.Append("</tbody>"); html.Append("</table>"); } #endregion html.Append("<script> function SearchPageModelOrder(searchFormId, value) { var oldValue = $(\"input[name='[PageModel_Order]']\").val(); var newValue = \"\"; if (oldValue == \"\" || oldValue == value + \"|Desc\") $(\"input[name='[PageModel_Order]']\").val(value + \"|Asc\"); else $(\"input[name='[PageModel_Order]']\").val(value + \"|Desc\"); $(\"input[name='[PageModel_CheckSearch]']\").val(\"0\");$(\"#\" + searchFormId).submit();}function SearchPageModelPage(searchFormId, value) {$(\"input[name='[PageModel_PageIndex]']\").val(value);$(\"input[name='[PageModel_CheckSearch]']\").val(\"0\");$(\"#\" + searchFormId).submit();} function SearchPageModelPageJmp(searchFormId) {var pindex = $(\"input[name='[psome_name]']\").val();$(\"input[name='[PageModel_PageIndex]']\").val(pindex);$(\"#\" + searchFormId).submit();}"); string js = "function PageModelCheck(v) {var id = v.split('_')[1]; var oldValue=$(\"input[name='[PageModel_SelectIds]']\").val(); if ($(\"#\" + v).is(\":checked\")) { if (id == \"All\") { $(\"input:checkbox\").each(function (i, ele) { var cid = $(ele).attr(\"id\"); if (cid.indexOf(\"pageModelCheck\") >= 0) { $(ele).attr(\"checked\", true); } }); $(\"input[name='[PageModel_SelectIds]']\").val(id); } else { if (oldValue.indexOf(id) < 0) { var newValue = oldValue + \"|\" + id; $(\"input[name='[PageModel_SelectIds]']\").val(newValue); } } } else { if (id == \"All\") { $(\"input:checkbox\").each(function (i, ele) { var cid = $(ele).attr(\"id\"); if (cid.indexOf(\"pageModelCheck\") >= 0) { $(ele).attr(\"checked\", false); } }); $(\"input[name='[PageModel_SelectIds]']\").val(\"\"); } else { if (oldValue.indexOf(id) >= 0) { var newValue = oldValue.replace(\"|\"+id,\"\"); $(\"input[name='[PageModel_SelectIds]']\").val(newValue); } } } }"; html.Append(js); html.Append(" function PageModeSelectIds() { var ids = $(\"input[name='[PageModel_SelectIds]']\").val(); return ids;}"); html.Append(" </script>"); return MvcHtmlString.Create(html.ToString()); } private List<PageRow> CreateRows() { var rows = new List<PageRow>(); //ModelMetadataProvider provider = ModelMetadataProviders.Current; //ModelMetadata containerMetadata = new ModelMetadata(provider, null, () => null, typeof(T), null); //var properties = containerMetadata.Properties.Select(m => m.PropertyName); if (this.DataSource != null && this.DataSource.Count() > 0 && this.Colums != null && this.Colums.Count > 0) { foreach (var data in this.DataSource) { var row = new PageRow(); if (!string.IsNullOrEmpty(this.SourcePrimaryKey)) { var keyValue = data.GetType().GetProperty(this.SourcePrimaryKey).GetValue(data, null); row.SourcePrimaryKey = keyValue == null ? Guid.NewGuid().ToString() : keyValue.ToString(); } else { row.SourcePrimaryKey = Guid.NewGuid().ToString(); } foreach (var colum in this.Colums) { if (!string.IsNullOrEmpty(colum.Field)) { var colValue = data.GetType().GetProperty(colum.Field).GetValue(data, null); row.RowData.Add(new RowItem() { ColumId = colum.Id, Vaule = colValue, CheckFieldColum = true}); } else { var html = Format(colum.Format, data); row.RowData.Add(new RowItem() { ColumId = colum.Id, Vaule = HttpUtility.HtmlEncode(html), CheckFieldColum = false }); } } rows.Add(row); } } return rows; } /// <summary> /// 執行委託 /// </summary> /// <param name="format">lambda表達示</param> /// <param name="arg">委託參數</param> /// <returns></returns> private HelperResult Format(Func<T, object> format, dynamic arg) { var result = format.Invoke(arg); return new HelperResult(tw => { var helper = result as HelperResult; if (helper != null) { helper.WriteTo(tw); return; } IHtmlString htmlString = result as IHtmlString; if (htmlString != null) { tw.Write(htmlString); return; } if (result != null) { tw.Write(HttpUtility.HtmlEncode(result)); } }); } /// <summary> /// 得到一個數左右多少個的起始數 /// </summary> /// <param name="helper"></param> /// <param name="currentNumber">當前數</param> /// <param name="maxNumber">最大數</param> /// <param name="showCount">一共多少個</param> /// <returns></returns> private Int64 GetStartNumber(Int64 currentNumber, Int64 maxNumber, int showCount) { var arr = new List<Int64>(); var pAvg = showCount / 2;//左右顯示個數 for (int i = 1; i <= pAvg; i++) { if (currentNumber - i > 0) { arr.Add(currentNumber - i); } if (currentNumber + i <= maxNumber) { arr.Add(currentNumber + i); } } arr.Add(currentNumber); if (arr.Count < 10) { var le = showCount - arr.Count; var min = arr.Min(); var max = arr.Max(); for (int i = 1; i <= le; i++) { if (min == 1 && max + 1 <= maxNumber) { arr.Add(max + 1); } if (max == maxNumber && min - 1 >= 1) { arr.Add(min - 1); } } } return arr.Min(); } private ModelMetadata GetModelMetadata<T>(string PropertyName) { ModelMetadataProvider provider = ModelMetadataProviders.Current; ModelMetadata containerMetadata = new ModelMetadata(provider, null, () => null, typeof(T), null); var metadata = containerMetadata.Properties.FirstOrDefault(m => m.PropertyName == PropertyName); return metadata; } public string ToHtmlString() { return this.ToMvcHtmlString().ToHtmlString(); } } }
9.添加一個設置對Html的替換規則類:MvcHtmlWrapper.csui
using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using System.Text; using System.Web; using System.Web.Mvc; namespace System.Web.Mvc { /// <summary> /// MvcHtmlString包裝器 /// 用於設置對Html的替換規則並在輸出時統一處理顯示Html /// </summary> public class MvcHtmlWrapper : IHtmlString { /// <summary> /// 構建一個MvcHtmlWrapper,若是是MvcHtmlWrapper則直接返回, /// 若是是是其它類型則構造MvcHtmlWrapper後返回 /// </summary> /// <param name="str">IHtmlString類型,實現了ToHtmlString接口的類型</param> /// <returns></returns> public static MvcHtmlWrapper Create(IHtmlString str) { Contract.Requires(str != null); if (str is MvcHtmlWrapper) return str as MvcHtmlWrapper; if (str is MvcHtmlString) return new MvcHtmlWrapper(str); Contract.Assert(false); return null; } IHtmlString HtmlStringInterface { get; set; } private string _htmlString; /// <summary> /// 獲取MvcHtmlString所生成的Html字符串 /// </summary> public string HtmlString { get { return _htmlString ?? (_htmlString = HtmlStringInterface.ToHtmlString()); } } /// <summary> /// 用於替換的Dict /// </summary> public List<Tuple<string, string>> ReplaceDict { get; set; } /// <summary> /// 構造MvcHtmlString包裝器 /// </summary> /// <param name="str">MvcHtmlString的實例,不容許爲空</param> MvcHtmlWrapper(IHtmlString str) { Contract.Requires(str != null); HtmlStringInterface = str; ReplaceDict = new List<Tuple<string, string>>(); } /// <summary> /// 對ToHtmlString進行了重寫, 輸出HtmlString的內容,並按替換規則進行了替換 /// </summary> /// <returns></returns> public string ToHtmlString() { return ToString(); } /// <summary> /// 對ToString進行了重寫, 輸出HtmlString的內容,並按替換規則進行了替換 /// </summary> /// <returns></returns> public override string ToString() { var sb = new StringBuilder(HtmlString); foreach (var item in ReplaceDict) { if (!string.IsNullOrEmpty(item.Item1)) { sb.Replace(item.Item1, item.Item2); } } return sb.ToString(); } /// <summary> /// 添加替換原則 /// </summary> /// <param name="item1">被替換的字符串</param> /// <param name="item2">替換爲的字符串</param> internal void Add(string item1, string item2) { ReplaceDict.Add(Tuple.Create(item1, item2)); } } }
10.添加一個MVC Html的擴展類:MvcHtmlStringExtension.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.Contracts; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Web; using System.Web.Mvc; namespace System.Web.Mvc { [EditorBrowsable(EditorBrowsableState.Never)] public static class MvcHtmlStringExtension { /// <summary> /// 擴展分頁查詢表 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="helper"></param> /// <param name="SearchFormId">要查詢的form表單ID</param> /// <returns></returns> public static PageModel<T> PageTableFor<T>(this HtmlHelper<PageModel<T>> helper, string SearchFormId) where T : class { var model = helper.ViewData.Model; model = model.SetSearchFormId(SearchFormId); return model; } #region ForSearch /// <summary> /// 爲當前表單元素添加搜索條件 /// </summary> /// <param name="str"></param> /// <param name="method">搜索方法</param> /// <param name="prefix">前綴</param> /// <param name="hasId">是否顯示Id,默認false</param> /// <param name="orGroup">若是想要支援Or,請設置一個Or分組</param> /// <returns></returns> public static MvcHtmlWrapper ForSearch(this IHtmlString str, QueryMethod? method, string prefix = "", bool hasId = false, string orGroup = "") { var wrapper = MvcHtmlWrapper.Create(str); Contract.Assert(null != wrapper); if (!method.HasValue) return wrapper; var html = wrapper.HtmlString; #region 若是是CheckBox,則去掉hidden if (html.Contains("type=\"checkbox\"")) { var checkMatch = Regex.Match(html, "<input name=\"[^\"]+\" type=\"hidden\" [^>]+ />"); if (checkMatch.Success) { wrapper.Add(checkMatch.Groups[0].Value, string.Empty); } } #endregion #region 替換掉Name var match = Regex.Match(html, "name=\"(?<name>[^\"]+)\""); var strInsert = ""; if (!string.IsNullOrWhiteSpace(prefix)) { strInsert += string.Format("({0})", prefix); } if (!string.IsNullOrWhiteSpace(orGroup)) { strInsert += string.Format("{{{0}}}", orGroup); } if (match.Success) { wrapper.Add(match.Groups[0].Value, string.Format("name=\"[{1}]{2}{0}\"", match.Groups[1].Value, method, strInsert)); } #endregion return wrapper; } #endregion } }
11.添加一個模型映射類:SearchModelBinder.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; namespace System.Web.Mvc { /// <summary> /// 對SearchModel作爲Action參數的綁定 /// </summary> public class SearchModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var model = (PageModel)(bindingContext.Model ?? new PageModel()); var dict = controllerContext.HttpContext.Request.Params; var keys = dict.AllKeys.Where(c => c.StartsWith("["));//咱們認爲只有[開頭的爲須要處理的 if (keys.Count() != 0) { foreach (var key in keys) { if (!key.StartsWith("[")) continue; var val = dict[key]; //處理無值的狀況 if (string.IsNullOrEmpty(val)) continue; if (key == "[PageModel_Order]")//排序 { var arr = val.Split('|'); if (arr.Length == 2) { model.Order = new QueryOrder() { Field = arr[0], Order = (OrderType)Enum.Parse(typeof(OrderType), arr[1]) }; } continue; } if (key == "[PageModel_PageIndex]")//頁碼 { try { var pindex = int.Parse(val); if (pindex > 1) model.PageIndex = pindex; else model.PageIndex = 1; if (keys.Contains("[PageModel_PageTotal]")) { var pt = int.Parse(dict["[PageModel_PageTotal]"]); if (pindex > pt) { model.PageIndex = 1; } } } catch { model.PageIndex = 1; } continue; } if (key == "[PageModel_PageTotal]") { continue; } if (key == "[PageModel_PageSize]")//每頁顯示數量 { try { var pSize = int.Parse(val); if (pSize > 0) model.PageSize = pSize; else model.PageSize = 20; } catch { model.PageSize = 20; } continue; } if (key == "[PageModel_CheckSearch]") { if (val == "1") { //model.che = 1; } continue; } if (key == "[PageModel_SelectIds]") { if (val == "All") { model.SelectAll = true; } else { model.SelectAll = false; model.SelectPrimaryKeys = val.Split('|').Where(m => m != "").ToList(); } continue; } if (key == "[psome_name]") { continue; } AddSearchItem(model, key, val); } } return model; } /// <summary> /// 將一組key=value添加入PageModel.SearchQuery /// </summary> /// <param name="model">PageModel</param> /// <param name="key">當前項的HtmlName</param> /// <param name="val">當前項的值</param> public static void AddSearchItem(PageModel model, string key, string val) { string field = "", prefix = "", orGroup = "", method = ""; var keywords = key.Split(']', ')', '}'); //將Html中的name分割爲咱們想要的幾個部分 foreach (var keyword in keywords) { if (Char.IsLetterOrDigit(keyword[0])) field = keyword; var last = keyword.Substring(1); if (keyword[0] == '(') prefix = last; if (keyword[0] == '[') method = last; if (keyword[0] == '{') orGroup = last; } if (string.IsNullOrEmpty(method)) return; if (!string.IsNullOrEmpty(field)) { var item = new ConditionItem { Field = field, Value = val.Trim(), Prefix = prefix, OrGroup = orGroup, Method = (QueryMethod)Enum.Parse(typeof(QueryMethod), method) }; model.SearchQuery.Add(item); } } } }
到此類庫封閉完畢。咱們將WEB引用此類庫。
12.在Global.asax中添加:
ModelBinders.Binders.Add(typeof(PageModel), new SearchModelBinder());
13.如今咱們WEB的Models中添加一個UserModel.cs進行實例展現:
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Web; namespace MvcApplication.Models { public class UserModel { [Display(Name = "編號")] public virtual string Id { get; set; } [Display(Name = "姓名")] public virtual string Name { get; set; } /// <summary> /// true:男 false:女 /// </summary> [Display(Name = "性別")] public virtual bool IsSex { get; set; } [Display(Name = "生日")] public virtual DateTime Birthday { get; set; } [Display(Name="性別")] public string SexName { get { return this.IsSex ? "男" : "女"; } } } }
14.修改HomeController:
using MvcApplication.Models; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcApplication.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult Table(PageModel model) { var data = CreateData(); var dCount = data.Count; data = data.Skip((model.PageIndex - 1) * model.PageSize).Take(model.PageSize).ToList(); return PartialView(model.Record<UserModel>(data, dCount)); } private IList<UserModel> CreateData() { var list = new List<UserModel>(); for (int i = 0; i < 100; i++) { list.Add(new UserModel() { Id=i.ToString(), Name="姓名"+i.ToString(), IsSex=true, Birthday=DateTime.Now }); } return list; } public ActionResult About() { ViewBag.Message = "你的應用程序說明頁。"; return View(); } public ActionResult Contact() { ViewBag.Message = "你的聯繫方式頁。"; return View(); } } }
15.修改Index.cshtml:
@{ ViewBag.Title = "主頁"; } @section featured { } <div id="tb001"> @Html.Action("Table") </div>
16.添加Table視圖:
@model PageModel<MvcApplication.Models.UserModel> @{ Layout = null; var ajaxOption = new AjaxOptions() { HttpMethod = "Post", UpdateTargetId = "tb001", OnBegin = "$('#pageMode_tableConetnt').mask();", OnComplete = "$('#pageMode_tableConetnt').unmask();", InsertionMode = InsertionMode.Replace }; } @using (Ajax.BeginForm("Table", "Home", null, ajaxOption, new { @id = "PageModel_Form" })) { <div> <div class="baseui-box"> <div class="baseui-box-head"> <h3 class="baseui-box-head-title">查詢</h3> <span class="baseui-box-head-text">Search</span> </div> <div class="baseui-box-container"> <div class="baseui-box-content"> 姓名: @Html.TextBox(Model.SearchName(m => m.Name), Model.SearchValue(m => m.Name), new { @class = "baseui-input" }).ForSearch(QueryMethod.Like) <input type="submit" value="查詢" class="baseui-button baseui-button-sorange" /> </div> </div> </div> <br /> <div class="baseui-box"> <div class="baseui-box-head"> <a href="@Url.Action("Add")" data-dialog-title="添加產品類型" data-dialog="true"> <i class="iconfont"></i> 添加 </a> </div> <div class="baseui-box-container"> <div class="baseui-box-content" style="padding: 0px !important;"> <div id="pageMode_tableConetnt"> @(Html.PageTableFor("PageModel_Form") .SetClass("baseui-table") .SetShowCheckBox(false) .SetSourceKey(m => m.Id) .ColumFor(m => m.Name) .ColumFor(m=>m.SexName) .Colum("生日",m=>m.Birthday.ToShortDateString()) .Colum("操做", @<text> @Html.ActionLink("修改", "Edit", new { id = @item.Id } ,new { data_dialog = "true", data_dialog_title = "修改產品類型" }) | @Ajax.ActionLink("刪除", "Delete", new { id = @item.Id }, ajaxOption , new { confirm_show = "true", confirm_tile = "提示", confirm_content = "是否刪除?", confirm_height = 210 }) </text>) ) </div> </div> </div> </div> </div> }
如今,咱們看看運行效果:
當咱們在姓名查詢框中輸入:張三
如今添加斷點:
這樣處理後,本身再進行處理封裝是否是很方便呢。
有些功能還沒有實現,請自行修改
本實例到此結束,若有不懂的地方請留言,若是你們以爲好請支持留言,若是有更好的處理方法請留言告知,不勝感激,在此謝謝了!!!