跟我一起學習ASP.NET 4.5 MVC4.0(五)


前面幾篇文章介紹了一下ASP.NET MVC中的一些基礎,今天我們一起來學習一下在ASP.NET MVC中控件的封裝。在頁面中我們會經常使用到Html對象,來程序控件,當然這里的控件不是說ASP.NET中包含很多ViewState或其他信息的控件。在ASP.NET MVC中控件就是擴展方法,主要對HtmlHelper實例的擴展,不過這里主要會提到CheckBoxList和RadioButtonList的擴展,因為在微軟自帶的控件中是沒有這兩個控件存在的,所以我們需要自己擴展。最后還會介紹一下,Html.CheckBoxFor這個控件在使用時會有兩個值,在服務端進行判斷的結果。

 

ASP.NET MVC(包含MVC3.0,MVC4.0)中的控件都在System.Web.Mvc中,這里需要了解一下HtmlMvcString和普通的string的區別。在我看來HtmlMvcString就是對string進行編碼,使得瀏覽器能夠正確解析HTML字符串。這樣在前台顯示時就不需要使用Html.Raw方法對字符串進行編碼,否則顯示的字符串將不會解析成HTML代碼。這個只需了解就可以了,有興趣可以試試就知道所以然了,所以MVC控件都需要返回這個對象。

 

在ASP.NET MVC中,lumbda表達式是很經常用的,而且非常好用。在頁面中聲明了一個模型,那樣就可以使用lumbda表達式進行實例的賦值和判斷,當然在對控件擴展時就會預見到表達式的使用,這些都是.NET3.5的特性,這里就不多贅述。 

 1          ///   <summary>
 2           ///  復選框擴展。
 3           ///   </summary>
 4           ///   <typeparam name="TModel"> 模型類型。 </typeparam>
 5           ///   <typeparam name="TProperty"> 屬性類型。 </typeparam>
 6           ///   <param name="helper"> HTML輔助方法。 </param>
 7           ///   <param name="expression"> lambda表達式。 </param>
 8           ///   <param name="selectList"> 選擇項。 </param>
 9           ///   <param name="htmlAttributes"> HTML屬性。 </param>
10           ///   <returns> 返回復選框MVC的字符串。 </returns>
11           public  static MvcHtmlString CheckBoxListFor<TModel, TProperty>( this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, ButtonFormatter formatter = ButtonFormatter.Horizontal, IDictionary< stringobject> htmlAttributes =  null)
12         {
13              if(selectList ==  null || expression ==  null)
14                  return MvcHtmlString.Empty;
15              string name = ExpressionHelper.GetExpressionText(expression);
16             List< string> values =  null;
17              object obj = helper.ViewData.Eval(name);
18              if(obj !=  null)
19                 values = obj.ToString().Split< string>();
20              else
21                 values =  new List< string>();
22 
23             StringBuilder sb =  new StringBuilder();
24              int index =  0;
25              foreach( var item  in selectList)
26             {
27                 TagBuilder tag =  new TagBuilder( " input ");
28                 tag.MergeAttributes< stringobject>(htmlAttributes);
29                 tag.MergeAttribute( " type "" checkbox "true);
30                 tag.MergeAttribute( " name ", name,  true);
31                 tag.MergeAttribute( " id ", name + index,  true);
32                 tag.MergeAttribute( " value ", item.Value,  true);
33                  if(values.Contains(item.Value))
34                     tag.MergeAttribute( " checked "" checked "true);
35                 sb.AppendLine(tag.ToString(TagRenderMode.SelfClosing) +  "   ");
36                 TagBuilder label =  new TagBuilder( " label ");
37                 label.MergeAttribute( " for ", name + index);
38                 label.InnerHtml = item.Text;
39                 sb.AppendLine(label.ToString());
40                  if(formatter == ButtonFormatter.Vertical)
41                     sb.AppendLine( " <br /> ");
42                 index++;
43             }
44              return  new MvcHtmlString(sb.ToString());
45         }
46 
47          ///   <summary>
48           ///  復選框擴展。
49           ///   </summary>
50           ///   <typeparam name="TModel"> 模型類型。 </typeparam>
51           ///   <typeparam name="TProperty"> 屬性類型。 </typeparam>
52           ///   <param name="helper"> HTML輔助方法。 </param>
53           ///   <param name="expression"> lambda表達式。 </param>
54           ///   <param name="selectList"> 選擇項。 </param>
55           ///   <param name="htmlAttributes"> HTML屬性。 </param>
56           ///   <returns> 返回復選框MVC的字符串。 </returns>
57           public  static MvcHtmlString CheckBoxListFor<TModel, TProperty>( this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, ButtonFormatter formatter,  object htmlAttributes)
58         {
59              return helper.CheckBoxListFor<TModel, TProperty>(expression, selectList, formatter,  new RouteValueDictionary(htmlAttributes));
60         }
61 
62          ///   <summary>
63           ///  枚舉復選框擴展。
64           ///   </summary>
65           ///   <typeparam name="TModel"> 模型類型。 </typeparam>
66           ///   <typeparam name="TProperty"> 屬性類型。 </typeparam>
67           ///   <param name="helper"> HTML輔助方法。 </param>
68           ///   <param name="expression"> lambda表達式。 </param>
69           ///   <param name="selectList"> 選擇項。 </param>
70           ///   <param name="htmlAttributes"> HTML屬性。 </param>
71           ///   <returns> 返回復選框MVC的字符串。 </returns>
72           public  static MvcHtmlString CheckBoxListFor<TModel, TProperty>( this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, ButtonFormatter formatter = ButtonFormatter.Horizontal,  object htmlAttributes =  nullstring classKey = Globals.Resource)
73         {
74              var selectList =  new List<SelectListItem>();
75             Globals.ForEach<TProperty>(p => {
76                 selectList.Add( new SelectListItem { Text = Globals.GetGlobalResourceByKey(p, classKey), Value = p.ToString() });
77             });
78              return helper.CheckBoxListFor<TModel, TProperty>(expression, selectList, formatter, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));

79         } 

上面的代碼各位有需要可以直接復制編譯后就可以使用了,其他涉及的資源的可以修改一下。而ButtonFormatter是一個枚舉類,主要用於設計橫排還是豎排的樣式,其他沒什么作用。這樣我們就可以很快的再前台使用CheckBoxList控件了,注意不是所有的頁面都有模型,或者說不是所有CheckBoxList都可以使用lumbda表達式來進行賦值等設置的,所以最好擴展一下CheckBoxList控件,那樣在各種情況都可以使用。

 

以上是我早期擴展的一個控件,其實很多地方都可以改的,比如屬性轉換,匿名類型可以直接實例化為RouteValueDictionary的,他的構造函數里就有這個。其中Globals.ForEach是我對枚舉迭代的一個擴展,即是循環枚舉中的每一個值顯示出來。而RadioButtonList的擴展和CheckBoxList的擴展是差不多的,只要標記替換一下就可以了,不過在大部分情況下比較少用,因為很多地方都被DropDownList替代。

 

 下面介紹一下在使用CheckBox時,服務端獲取是否選中的方法。假如你使用過這個控件就會發現,呈現的HTML代碼中包含兩個checkbox的input,只是其中一個被隱藏了,當我們使用submit按鈕提交時,在服務端獲得的值就會包含兩個input的值。為了解決這個問題,我們需要判斷一下到底有沒有被選中,不難發現,如果沒有被選中,這服務端獲取得到的值就只有一個False的值,如果選中了就會有兩個,一個True一個False,所以我們需要判斷到底服務端獲得的第一個值是False還是True,具體代碼可以看下面。

  1 /// <summary>

 2           ///  判斷是否被選中。
 3           ///   </summary>
 4           ///   <param name="form"> 路由實例對象。 </param>
 5           ///   <param name="key"> 路由鍵。 </param>
 6           ///   <param name="defaultValue"> 返回默認值。 </param>
 7           ///   <returns> 返回是否被選中。 </returns>
 8           public  static  bool IsChecked( this FormCollection form,  string key,  bool defaultValue =  false)
 9         {
10              var values = form.GetValues(key);
11              if(values!= null)
12                  return values[ 0].To< bool>(defaultValue);
13              return defaultValue;
14         }
15 
16          ///   <summary>
17           ///  判斷是否被選中。
18           ///   </summary>
19           ///   <param name="request"> 路由實例對象。 </param>
20           ///   <param name="key"> 路由鍵。 </param>
21           ///   <param name="defaultValue"> 返回默認值。 </param>
22           ///   <returns> 返回是否被選中。 </returns>
23           public  static  bool IsChecked( this HttpRequestBase request,  string key,  bool defaultValue =  false)
24         {
25              var values = request.Form.GetValues(key);
26              if(values !=  null)
27                  return values[ 0].To< bool>(defaultValue);
28              return defaultValue;
29         }

 其中To這個方法是我封裝類型轉換的方法,由於本系列沒有一個良好的規划,想到哪里就寫到哪里,很多達人看了可能不會有連續性。主要我還是推薦學基礎可以到MSDN或博客園里也有按照微軟Tutorial順序寫的教程,由於時間的關系今天到此結束。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM