从CheckboxList HTML Helper获取逗号分隔的字符串

时间:2015-04-02 05:26:15

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

我从互联网上获得了CheckboxListFor html帮助扩展程序的以下代码。目前,在SelectedValues中,它会从复选框列表中返回List<string>个选定值。我想在SelectedValues中获得逗号分隔的字符串。

谁能告诉我如何实现它?

以下是代码:

HTMLHelper扩展名:

        /// <summary>
    /// Returns a checkbox for each of the provided <paramref name="items"/>.
    /// </summary>
    public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string listName, IEnumerable<SelectListItem> items, object htmlAttributes = null)
    {
        var container = new TagBuilder("div");
        foreach (var item in items)
        {
            var label = new TagBuilder("label");
            label.MergeAttributes(new RouteValueDictionary(htmlAttributes), true);

            var cb = new TagBuilder("input");
            cb.MergeAttribute("type", "checkbox");
            cb.MergeAttribute("name", listName);
            cb.MergeAttribute("value", item.Value ?? item.Text);
            if (item.Selected)
                cb.MergeAttribute("checked", "checked");

            label.InnerHtml = cb.ToString(TagRenderMode.SelfClosing) + item.Text;

            container.InnerHtml += label.ToString();
        }

        return new MvcHtmlString(container.ToString());
    }

    private static IEnumerable<SelectListItem> GetCheckboxListWithDefaultValues(object defaultValues, IEnumerable<SelectListItem> selectList)
    {
        var defaultValuesList = defaultValues as IEnumerable;

        if (defaultValuesList == null)
            return selectList;

        IEnumerable<string> values = from object value in defaultValuesList
                                     select Convert.ToString(value, CultureInfo.CurrentCulture);

        var selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase);
        var newSelectList = new List<SelectListItem>();

        selectList.ForEach(item =>
        {
            item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
            newSelectList.Add(item);
        });

        return newSelectList;
    }

    /// <summary>
    /// Returns a checkbox for each of the provided <paramref name="items"/>.
    /// </summary>
    public static MvcHtmlString CheckBoxListFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TValue>> expression, 
        IEnumerable<SelectListItem> items, object htmlAttributes = null)
    {
        var listName = ExpressionHelper.GetExpressionText(expression);
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        items = GetCheckboxListWithDefaultValues(metaData.Model, items);
        return htmlHelper.CheckBoxList(listName, items, htmlAttributes);
    }

在视图中:

@Html.CheckBoxListFor(model => model.SelectedValues, Model.MySelectList)

型号:

public class MyViewModel
{        
      public SelectList MySelectList{ get; set; }

      public List<string> SelectedValues{ get; set; }

      //public string SelectedValues{ get; set; }   Can I get comma separated string here
}

请注意,我需要从帮助程序返回的逗号分隔字符串,而不是在我返回控制器操作列表后。

为什么我要尝试这样做?:

//Here in my model, I am getting `SelectedValues` which is a List<String>.
public ActionResult Index(MyViewModel model)
{
      //My code....
}

在视图中

//But I cannot save this list into RouteValueDictionary like:
var searchCriteria = new RouteValueDictionary();
searchCriteria["model.SelectedValues"] = Model.SelectedValues; // List<string> cannot be save here. That's why I needed comma separated string.
var viewDataDictionary = new ViewDataDictionary();
viewDataDictionary["searchCriteria"] = searchCriteria;

@Html.Partial("_MyPagingView", Model.MyList, viewDataDictionary)

_MyPagingView内部有一个完整的机制,只要点击下一页,就会调用Index操作。为了保持搜索状态,我们需要将搜索到的数据保存在RouteValueDictionary内。

2 个答案:

答案 0 :(得分:1)

您可以创建一个帮助方法,将SelectedValues添加到RouteValueDictionary

public void AddRoutes(List<string> values, string propertyName, RouteValueDictionary dictionary)
{
    for (int i = 0; i < values.Count; i++ )
    {
        string key = string.Format("{0}[{1}]", propertyName, i);
        dictionary[key] = values[i];
    }
}

然后将其用作

var searchCriteria = new RouteValueDictionary();
AddRoutes(Model.SelectedValues, "SelectedValues", searchCriteria);

并且避免创建隐藏输入并使用javascript

答案 1 :(得分:0)

我更喜欢更改视图模型的代码:

public class MyViewModel
{
    public SelectList MySelectList{ get; set; }

    public List<string> SelectedValues { get; set; }

    public string SelectedString
    {
        get
        {
            if (SelectedValues == null) return "";
            return string.Join(",", SelectedValues);
        }
        set
        {
            if (!string.IsNullOrEmpty(value))
            {
                SelectedValues = value.Split(',').ToList();
            }
        }
    }
}

您可以获取逗号分隔字符串:

//In controller
var selected = model.SelectedString; 

//In view
searchCriteria["model.SelectedValues"] = Model.SelectedString;