好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

为HtmlHelper添加一个RadioButtonList扩展方法

[ASP.NET MVC]为HtmlHelper添加一个RadioButtonList扩展方法

在 前面一篇文章 中,我们通过对HtmlHelper的扩展简化了对DropDownList(Single-Line-Select)和ListBox(Multiple-Line-Select)的绑定,以及对作为数据源的列表进行单独维护。现在我们为HtmlHelper/HtmlHelper<Model>添加一个RadioButtonList/RadioButtonListFor扩展方法实现一组RadioButton的绑定。[源代码从 这里 下载]

一、RadioButtonListFor的使用

我们先来显示一下扩展的RadioButtonListFor的方法的用法。如下所示的是作为Model的Person类型,其Gender(Male/Female)、MaritalStatus(Single/Married)和Country的选项列表通过独立的组件CodeManager进行单独维护。

    1:   public   class  Person
    2:  {
    3:       public   string  Name { get; set; }
    4:       public   string  Gender { get; set; }
    5:      [Display(Name =  "Marital Status" )]
    6:       public   string  MaritalStatus { get; set; }
    7:       public   string  Country { get; set; }
    8:  }

在一个针对Person对象进行编辑的强类型View(以Person作为Model)中我们进行了如下的定义。RadioButtonListFor方的最后一个参数(“Gender”、“MaritalStatus”和“Country”)表示对应列表的类别。

    1:  @using System.Web.UI.WebControls
    2:  @model Person
    3:  @{
    4:      ViewBag.Title = "Index";
    5:  }
    6:  @using (Html.BeginForm())
    7:  { 
    8:       <  table   id  ="container"  > 
    9:           <  tr  > 
   10:               <  td   class  ="label"  > @Html.LabelFor(m = >  m.Name): </  td  > 
   11:               <  td  > @Html.EditorFor(m = >  m.Name) </  td  > 
   12:           </  tr  > 
   13:            <  tr  > 
   14:               <  td   class  ="label"  > @Html.LabelFor(m = >  m.Gender): </  td  > 
   15:               <  td  > @Html.RadioButtonListFor(m = >  m.Gender, "Gender") </  td  > 
   16:           </  tr  > 
   17:            <  tr  > 
   18:               <  td   class  ="label"  > @Html.LabelFor(m = >  m.MaritalStatus): </  td  > 
   19:               <  td  > @Html.RadioButtonListFor(m = >  m.MaritalStatus, "MaritalStatus") </  td  > 
   20:           </  tr  > 
   21:            <  tr  > 
   22:               <  td   class  ="label"  > @Html.LabelFor(m = >  m.Country): </  td  > 
   23:               <  td  > @Html.RadioButtonListFor(m = >  m.Country, "Country", RepeatDirection.Vertical) </  td  > 
   24:           </  tr  >  
   25:           <  tr  > 
   26:               <  td   colspan  ="2"  ><  input   type  ="submit"   value  ="Save"   /></  td  > 
   27:           </  tr  >       
   28:       </  table  >     
   29:  }

下面这张图表示上面这个View在浏览器中呈现出来的样式,我们可以看到三组RadioButton被有效地生成出来。

二、维护选项列表的组件CodeManager

由于在一个应用中,作为绑定到“列表控件”上的选项列表可能会有很多,将它们进行单独地维护是一个理想的选择。作为模拟,我们创建了如下一个简单的CodeManager组件。我们将列表中的某个选项通过CodeDescription,其三个属性Code、Description分别表示其“值”和“显示文本”,Category表示类别(通过它对列表项进行分组)。CodeManager通过一个静态字段作为列表数据的存储,上面例子中使用到的三组列表维护于此。GetCodes方法用于返回指定“类别”的列表选项。

    1:   public   class  CodeDescription
    2:  {
    3:       public   string  Code { get; set; }
    4:       public   string  Description { get; set; }
    5:       public   string  Category{get;set;}
    6:   
    7:       public  CodeDescription( string  code,  string  description,  string  category)
    8:      {
    9:           this .Code = code;
   10:           this .Description = description;
   11:           this .Category = category;
   12:      }
   13:  }
   14:   public   static   class  CodeManager
   15:  {
   16:       private   static  CodeDescription[] codes =  new  CodeDescription[]
   17:      {
   18:           new  CodeDescription( "M" , "Male" , "Gender" ),
   19:           new  CodeDescription( "F" , "Female" , "Gender" ),
   20:           new  CodeDescription( "S" , "Single" , "MaritalStatus" ),
   21:           new  CodeDescription( "M" , "Married" , "MaritalStatus" ),
   22:           new  CodeDescription( "CN" , "China" , "Country" ),
   23:           new  CodeDescription( "US" , "Unite States" , "Country" ),
   24:           new  CodeDescription( "UK" , "Britain" , "Country" ),
   25:           new  CodeDescription( "SG" , "Singapore" , "Country" )
   26:      };
   27:       public   static  Collection<CodeDescription> GetCodes( string  category)
   28:      {
   29:          Collection<CodeDescription> codeCollection =  new  Collection<CodeDescription>();
   30:           foreach (var code  in  codes.Where(code=>code.Category == category))
   31:          {
   32:              codeCollection.Add(code);
   33:          }
   34:           return  codeCollection;
   35:      }
   36:  }

三、RadioButtonList/RadioButtonListFor扩展方法

如下所示的是RadioButtonList/RadioButtonListFor两个扩展方法的定义,参数codeCategory表示作为数据源的列表类别,而RepeatDirection 枚举类型则代表同组的RadioButton的排列方向,默认为水平。从上面的例子我们可以看到,我们通过这个参数将名称为Country的RadioButtonList进行了纵向排列。通过Html生成代码我们可以看出,我们采用了Table作为布局方式,实际上ASP.NET的RadioButtonList也是这么做的。

    1:   public   static    class  RadioButtonListExtensions
    2:  {
    3:       public   static  MvcHtmlString RadioButtonList( this  HtmlHelper htmlHelper,  string  name,   string  codeCategory, RepeatDirection repeatDirection = RepeatDirection.Horizontal, IDictionary< string ,  object > htmlAttributes =  null )
    4:      {
    5:          var codes = CodeManager.GetCodes(codeCategory);
    6:           return  GenerateHtml(name, codes, repeatDirection, htmlAttributes,  null );
    7:      }
    8:       public   static  MvcHtmlString RadioButtonListFor<TModel, TProperty>( this  HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression,  string  codeCategory, RepeatDirection repeatDirection =  RepeatDirection.Horizontal, IDictionary< string ,  object > htmlAttributes =  null )
    9:      {
   10:          var codes = CodeManager.GetCodes(codeCategory);
   11:          
   12:          ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
   13:           string  name = ExpressionHelper.GetExpressionText(expression);
   14:          var attributes = htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata);
   15:           foreach  (var item  in  attributes)
   16:          {
   17:              htmlAttributes.Add(item);
   18:          }
   19:           string  fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
   20:           string  stateValue = ( string )GetModelStateValue(htmlHelper,fullHtmlFieldName,  typeof ( string ));
   21:           return  GenerateHtml(fullHtmlFieldName, codes, repeatDirection, htmlAttributes, stateValue);
   22:      }
   23:   
   24:       internal   static   object  GetModelStateValue<TModel>(HtmlHelper<TModel> htmlHelper,  string  key, Type destinationType)
   25:      {
   26:          ModelState state;
   27:           if  (htmlHelper.ViewData.ModelState.TryGetValue(key,  out  state) && (state.Value !=  null ))
   28:          {
   29:               return  state.Value.ConvertTo(destinationType,  null );
   30:          }
   31:           return   null ;
   32:      }
   33:   
   34:       private   static  MvcHtmlString GenerateHtml( string  name, Collection<CodeDescription> codes, RepeatDirection repeatDirection, IDictionary< string ,  object > htmlAttributes,  string  stateValue =  null )
   35:      {
   36:          TagBuilder table =  new  TagBuilder( "table" );
   37:           int  i = 0;
   38:           if  (repeatDirection == RepeatDirection.Horizontal)
   39:          {
   40:              TagBuilder tr =  new  TagBuilder( "tr" );
   41:               foreach  (var code  in  codes)
   42:              {
   43:                  i++;
   44:                   string  id =  string .Format( "{0}_{1}" , name, i);
   45:                  TagBuilder td =  new  TagBuilder( "td" );
   46:                  td.InnerHtml = GenerateRadioHtml(name, id, code.Description, code.Code, (stateValue !=  null  && stateValue == code.Code), htmlAttributes);
   47:                  tr.InnerHtml+=td.ToString();
   48:              }
   49:              table.InnerHtml = tr.ToString();
   50:          }
   51:           else 
   52:          {
   53:               foreach  (var code  in  codes)
   54:              {
   55:                  TagBuilder tr =  new  TagBuilder( "tr" );
   56:                  i++;
   57:                   string  id =  string .Format( "{0}_{1}" , name, i);
   58:                  TagBuilder td =  new  TagBuilder( "td" );
   59:                  td.InnerHtml = GenerateRadioHtml(name, id, code.Description, code.Code, (stateValue !=  null  && stateValue == code.Code), htmlAttributes);
   60:                  tr.InnerHtml = td.ToString();
   61:                  table.InnerHtml += tr.ToString();
   62:              }
   63:          }
   64:           return   new  MvcHtmlString(table.ToString());
   65:      }
   66:   
   67:       private   static   string  GenerateRadioHtml( string  name,  string  id,  string  labelText,  string   value ,  bool  isChecked, IDictionary< string ,  object > htmlAttributes)
   68:      {
   69:          StringBuilder sb =  new  StringBuilder();
   70:   
   71:          TagBuilder label =  new  TagBuilder( "label" );
   72:          label.MergeAttribute( "for" , id);
   73:          label.SetInnerText(labelText);
   74:   
   75:          TagBuilder input =  new  TagBuilder( "input" );
   76:          input.GenerateId(id);
   77:          input.MergeAttribute( "name" , name);
   78:          input.MergeAttribute( "type" ,  "radio" );
   79:          input.MergeAttribute( "value" ,  value );
   80:          input.MergeAttributes(htmlAttributes);
   81:           if  (isChecked)
   82:          {
   83:              input.MergeAttribute( "checked" ,  "checked" );
   84:          }
   85:          sb.AppendLine(input.ToString());
   86:          sb.AppendLine(label.ToString());
   87:           return  sb.ToString();
   88:      }
   89:  }

作者: Artech
出处: http://artech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于为HtmlHelper添加一个RadioButtonList扩展方法的详细内容...

  阅读:74次