MVC5帮助器htmlAttributes

时间:2014-11-21 07:12:54

标签: c# asp.net-mvc html-helper

我正在尝试将htmlAttributes添加到现有帮助程序中:

public static MvcHtmlString ExCheckBox (this HtmlHelper helper, string name, bool? value, bool readOnly)
{
  return ExCheckBox(helper, name, value, readOnly, "");
}

public static MvcHtmlString ExCheckBox (this HtmlHelper helper, string name, bool? value, bool readOnly, string Label)
{
  var HTML = ExCheckBox(helper, name, value, readOnly, Label, new Dictionary<string, string>());
  return new MvcHtmlString(HTML.ToString());
}

public static MvcHtmlString ExCheckBox4 (this HtmlHelper helper, string name, bool? value, bool readOnly, string Label, object htmlAttributes)
{
  var HTML = ExCheckBox(helper, name, value, readOnly, Label, new RouteValueDictionary(htmlAttributes), new Dictionary<string, string>());
  return new MvcHtmlString(HTML.ToString());
}

public static MvcHtmlString ExCheckBox (this HtmlHelper helper, string name, object value, bool readOnly, string Label, IDictionary<string, string> Params)
    {
    string HTML = "";
    if (readOnly)
        HTML = String.Format("<label for='{0}'>{1}</label>", name, value == null ? "" : ((bool?)value == true ? "Yes" : "No"));
    else
        {
        string DropDownList = AddEmptyOption(System.Web.Mvc.Html.SelectExtensions.DropDownList(helper, name, GetDropDownListItems(value == null ? "" : value.ToString())).ToString());
        HTML += DropDownList;
        }
    HTML = AddCellsAndLabel(HTML, name, Label, Params);
    return new MvcHtmlString(HTML);
    }

public static List<SelectListItem> GetDropDownListItems (string currentValue)
    {
    var list = new List<SelectListItem>();
    var item = new SelectListItem();

    item.Text = "No";
    item.Value = "false";
    if (currentValue == false.ToString())
        item.Selected = true;
    list.Add(item);
    item = new SelectListItem();
    item.Text = "Yes";
    item.Value = "true";
    if (currentValue == true.ToString())
        item.Selected = true;
    list.Add(item);

    return list;
    }

   private static string AddCellsAndLabel (string ControlHTML, string name, string Label, IDictionary<string, string> Params)
            {
            if (!String.IsNullOrEmpty(Label))
                {
                string ControlColSpan = "";
                string LabelColSpan = "";
                if (Params.ContainsKey(HtmlHelperParams.ControlColSpan))
                    {
                    ControlColSpan = "colspan='" + Params[HtmlHelperParams.ControlColSpan] + "'";
                    }
                if (Params.ContainsKey(HtmlHelperParams.LabelColSpan))
                    {
                    LabelColSpan = "colspan='" + Params[HtmlHelperParams.LabelColSpan] + "'";
                    }
                ControlHTML = String.Format("<td " + LabelColSpan + "  class=\"Label\"><label for=\"{0}\">{1}</label></td>", name, Label) + "<td " + ControlColSpan + " class=\"ControlCell\">" + ControlHTML + "</td>";
                }
            return ControlHTML;
            }

前两个助手工作得很好,第三个ExCheckBox4我得到了这个错误:

  

没有超载方法&#39; ExCheckBox&#39;需要7个参数

感谢您的建议。

3 个答案:

答案 0 :(得分:1)

您的代码存在许多问题,包括

  1. 没有强烈打字
  2. 您覆盖控件名称属性,因此它不会绑定到您的 回帖后的模特
  3. 你在表格中使用它,假设这是在for中呈现的 循环,您的渲染重复id(无效的HTML)和name 属性(不会在回发后绑定到你的收藏)。
  4. 您的呈现<label>元素只读它但不是 与控件相关联(语义不正确)。
  5. 您的扩展程序接受值为object的值,但会抛出 如果不是nullable bool
  6. ,则为例外

    尝试以下

    public static MvcHtmlString XCheckBox<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, bool?>> expression, bool isReadOnly, int labelColumns, int controlColumns, object htmlAttributes)
    {
      ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
      string label = metaData.GetDisplayName();
      string name = ExpressionHelper.GetExpressionText(expression);
      StringBuilder html = new StringBuilder();      
      if (isReadOnly)
      {
        html.Append(ReadonlyLabelCell(label, labelColumns));
        html.Append(ReadonlyValueCell((bool?)metaData.Model, controlColumns));
      }
      else
      {
        html.Append(LabelCell(label, name, labelColumns));
        html.Append(ControlCell(name, (bool?)metaData.Model, controlColumns, htmlAttributes));
      }     
      return MvcHtmlString.Create(html.ToString());
    }
    
    private static string ReadonlyLabelCell(string label, int colSpan)
    {
      TagBuilder span = new TagBuilder("span");
      span.InnerHtml = label;
      TagBuilder cell = new TagBuilder("td");
      cell.AddCssClass("label");
      cell.MergeAttribute("colspan", colSpan.ToString());
      cell.InnerHtml = span.ToString();
      return cell.ToString();
    }
    
    private static string ReadonlyValueCell(bool? value, int colSpan)
    {
      TagBuilder span = new TagBuilder("span");
      span.InnerHtml = value.HasValue ? value.Value ? "Yes" : "No" : "Not set";
      TagBuilder cell = new TagBuilder("td");
      cell.AddCssClass("readonly"); // added class for styling
      cell.MergeAttribute("colspan", colSpan.ToString());
      cell.InnerHtml = span.ToString();
      return cell.ToString();
    }
    
    private static string LabelCell(string labelText, string controlName, int colSpan)
    {
      TagBuilder label = new TagBuilder("label");
      label.MergeAttribute("for", controlName);
      label.InnerHtml = labelText;
      TagBuilder cell = new TagBuilder("td");
      cell.AddCssClass("label");
      cell.MergeAttribute("colspan", colSpan.ToString());
      cell.InnerHtml = label.ToString();
      return cell.ToString();
    }
    
    private static string ControlCell(string controlName, bool? value, int colSpan, object htmlAttributes)
    {
      StringBuilder html = new StringBuilder();
      TagBuilder option = new TagBuilder("option");
      option.MergeAttribute("value", string.Empty);
      option.InnerHtml = "Not set";
      html.Append(option.ToString());
      option = new TagBuilder("option");
      option.MergeAttribute("value", "true");
      if (value.HasValue && value.Value)
      {
        option.MergeAttribute("selected", "selected");
      }
      option.InnerHtml = "Yes";
      html.Append(option.ToString());
      option = new TagBuilder("option");
      option.MergeAttribute("value", "false");
      if (value.HasValue && !value.Value)
      {
        option.MergeAttribute("selected", "selected");
      }
      option.InnerHtml = "No";
      html.Append(option.ToString());
      TagBuilder select = new TagBuilder("select");
      select.MergeAttribute("name", controlName);
      select.MergeAttribute("id", HtmlHelper.GenerateIdFromName(controlName));
      select.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
      select.InnerHtml = html.ToString();
      TagBuilder cell = new TagBuilder("td");
      cell.AddCssClass("controlcell");
      cell.MergeAttribute("colspan", colSpan.ToString());
      cell.InnerHtml = select.ToString();
      return cell.ToString();
    }
    

    然后是其他重载

    public static MvcHtmlString XCheckBox<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, bool?>> expression, bool isReadOnly)
    {
      return XCheckBox(helper, expression, isReadOnly, 1, 1, null);
    }
    

    使用如下

    @Html.XCheckBoxFor(m => m.Client.Rotates, false, 1, 1, new { @class = "form-control" })
    

答案 1 :(得分:0)

很明显 没有接受此参数的方法(在ExCheckBox4正文中)

var HTML = ExCheckBox(helper, name, value, readOnly, Label, new RouteValueDictionary(htmlAttributes), new Dictionary<string, string>());

答案 2 :(得分:0)

您可能需要将其更改为

public static MvcHtmlString ExCheckBox4 (this HtmlHelper helper, string name, bool? value, bool readOnly, string Label, object htmlAttributes)
{
 var HTML = helper.ExCheckBox(name, value, readOnly, Label, new RouteValueDictionary(htmlAttributes));
 return new MvcHtmlString(HTML.ToString());
}