MVC地區多級聯動擴展實現(非遞歸形式),mvc遞歸
MVC前台界面調用方式如下:
@Html.AreaDropDownList("areaCode", areaCode, 3, string.Empty)
參數說明:
第一個參數控件的名稱;
第二個參數選中的地區編碼;
第三個參數地區層級;
第四個參數根級地區;
地區數據庫表設計如下:

下拉列表的擴展:

![]()
1 #region 下拉列表
2
3 /// <summary>
4 /// 聯動下拉列表
5 /// </summary>
6 /// <param name="htmlHelper">被擴展的HtmlHelper實例</param>
7 /// <param name="expression">獲取數據集合</param>
8 /// <param name="level">顯示多少級</param>
9 /// <param name="defaultValue">TProperty類型的默認值(如string默認值為"")</param>
10 /// <param name="rootItems">獲取根級列表數據</param>
11 /// <param name="getParentID">獲取列表項的ParentID方法</param>
12 /// <param name="getChildItems">獲取子級列表數據集合方法</param>
13 /// <param name="getChildSelectDataUrl">獲取子級列表數據的遠程地址</param>
14 /// <returns>html代碼</returns>
15 public static MvcHtmlString LinkageDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, TProperty defaultValue, int level, Dictionary<TProperty, string> rootItems,Func<TProperty, TProperty> getParentID, Func<TProperty, Dictionary<TProperty, string>> getChildItems,string getChildSelectDataUrl,string optionLabel = "請選擇")
16 {
17 ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
18
19 return LinkageDropDownList(htmlHelper, ExpressionHelper.GetExpressionText(expression), (TProperty)metadata.Model, defaultValue, level, rootItems, getParentID,getChildItems,getChildSelectDataUrl,optionLabel);
20 }
21
22
23 /// <summary>
24 /// 聯動下拉列表
25 /// </summary>
26 /// <param name="htmlHelper">被擴展的HtmlHelper實例</param>
27 /// <param name="level">顯示多少級</param>
28 /// <param name="defaultValue">TProperty類型的默認值(如string默認值為"")</param>
29 /// <param name="name">下拉列表表單項名</param>
30 /// <param name="selectedValue">當前選中值</param>
31 /// <param name="rootItems">獲取根級列表數據</param>
32 /// <param name="getParentId">獲取列表項的ParentID方法</param>
33 /// <param name="getChildItems">獲取子級列表數據集合方法</param>
34 /// <param name="getChildSelectDataUrl">獲取子級列表數據的遠程地址</param>
35 /// <returns>html代碼</returns>
36 public static MvcHtmlString LinkageDropDownList<TProperty>(this HtmlHelper htmlHelper, string name, TProperty selectedValue,TProperty defaultValue, int level, Dictionary<TProperty, string> rootItems, Func<TProperty, TProperty> getParentId, Func<TProperty, Dictionary<TProperty, string>> getChildItems, string getChildSelectDataUrl, string optionLabel = "請選擇")
37 {
38 string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
39 //select data init
40 Stack<Dictionary<TProperty, string>> stack = new Stack<Dictionary<TProperty, string>>();
41
42 //如果有選中的值,則查找其所在列表前面的所有列表
43 IList<TProperty> selectedValues = new List<TProperty>();
44 if (selectedValue != null && !selectedValue.Equals(defaultValue))
45 {
46 TProperty itemId = selectedValue;
47 TProperty parentItemId = getParentId(itemId);
48 while (!itemId.Equals(defaultValue) && !parentItemId.Equals(defaultValue))
49 {
50 stack.Push(getChildItems(parentItemId));
51 selectedValues.Add(itemId);
52 itemId = parentItemId;
53 parentItemId = getParentId(itemId);
54 }
55 if (rootItems.Count() > 0)
56 {
57 TProperty rootId = getParentId(rootItems.First().Key);
58 if (!itemId.Equals(rootId))
59 {
60 stack.Push(rootItems);
61 selectedValues.Add(itemId);
62 }
63 }
64 }
65 else
66 {
67 TProperty rootItemID = rootItems.Select(n => n.Key).FirstOrDefault();
68 stack.Push(rootItems);
69 }
70
71 //生成標簽
72 TagBuilder containerBuilder = new TagBuilder("span");
73 containerBuilder.MergeAttribute("plugin", "linkageDropDownList");
74 var data = new Dictionary<string, object>();
75 data.TryAdd("GetChildSelectDataUrl", getChildSelectDataUrl);
76 data.TryAdd("ControlName", name);
77 data.TryAdd("Level", level);
78 data.TryAdd("OptionLabel", optionLabel);
79 data.TryAdd("DefaultValue", defaultValue.ToString());
80 containerBuilder.MergeAttribute("data", Json.Encode(data));
81 int currentIndex = 0;
82 while (stack.Count > 0)
83 {
84 Dictionary<TProperty, string> dictionary = stack.Pop();
85 IEnumerable<SelectListItem> selectList = dictionary.Select(n => new SelectListItem() { Selected = selectedValues.Contains(n.Key), Text = n.Value, Value = n.Key.ToString() });
86 containerBuilder.InnerHtml += "\r\n" + htmlHelper.DropDownList(string.Format("{0}_{1}", name, currentIndex), selectList,
87 optionLabel, new { @class = "tn-dropdownlist" });
88 currentIndex++;
89 }
90 containerBuilder.InnerHtml += "\r\n" + htmlHelper.Hidden(name);
91 return MvcHtmlString.Create(containerBuilder.ToString());
92 }
93
94 #endregion
View Code
對外的調用的實現:
1 /// <summary>
2 /// 地區下拉列表
3 /// </summary>
4 /// <param name="htmlHelper">被擴展的htmlHelper實例</param>
5 /// <param name="expression">選擇實體中類別屬性的lamda表達式</param>
6 /// <param name="areaLevel">地區層級(默認取站點地區配置)</param>
7 /// <param name="rootAreaCode">根級地區(默認取站點地區配置)</param>
8 public static MvcHtmlString AreaDropDownListFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, string>> expression, int? areaLevel = null, string rootAreaCode = null)
11 {
12 string getChildAreasUrl = "/Channel/GetChildAreas";//獲取子地區的遠程地址,(AreaCode,name)的JSON數據
13 if (areaLevel == null)
15 {
16 areaLevel = 0;//區域設置級別,可以作為配置文件獲取
17 }
18 return htmlHelper.LinkageDropDownListFor<TModel, string>(expression, string.Empty, areaLevel.Value, 獲取根級區域的(AreaCode,name)鍵值對,獲取當前選中區域的父區域, 獲取當前的子區域, getChildAreasUrl);
21 }
22
23 /// <summary>
24 /// 地區下拉列表
25 /// </summary>
26 /// <param name="htmlHelper">被擴展的htmlHelper實例</param>
27 /// <param name="name">控件name屬性</param>
28 /// <param name="name">選中的地區編碼</param>
29 /// <param name="areaLevel">地區層級(默認取站點配置)</param>
30 /// <param name="rootAreaCode">根級地區(默認取站點地區配置)</param>
31 public static MvcHtmlString AreaDropDownList(this HtmlHelper htmlHelper, string name, string value, int? areaLevel = null, string rootAreaCode = null)
32 {
33 string getChildAreasUrl = "/Channel/GetChildAreas";//獲取子地區的遠程地址,(AreaCode,name)的JSON數據
34 if (areaLevel == null)
36 {
37 areaLevel = 0;//區域設置級別,可以作為配置文件獲取
38 }
39 return htmlHelper.LinkageDropDownList<string>(name, value, string.Empty, areaLevel.Value, 獲取根級區域的(AreaCode,name)鍵值對, 獲取當前選中區域的父區域, 獲取選中地區當前的子區域, getChildAreasUrl);
42 }