0

绝望中,我创建了一个 CheckboxListFor 方法,如下所示(我从某个地方撕掉了这个,可能在这里)。

public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IEnumerable<TProperty>>> expression, MultiSelectList multiSelectList, object htmlAttributes = null)
        {
            //Derive property name for checkbox name
            var body = expression.Body as MemberExpression;
            string propertyName = body.Member.Name;

            //Get currently select values from the ViewData model
            IEnumerable<TProperty> list = expression.Compile().Invoke(htmlHelper.ViewData.Model);

            //Convert selected value list to a List<string> for easy manipulation
            var selectedValues = new List<string>();

            if (list != null)
            {
                selectedValues = new List<TProperty>(list).ConvertAll(i => i.ToString());
            }

            //Create div
            var divTag = new TagBuilder("div");
            divTag.MergeAttributes(new RouteValueDictionary(htmlAttributes), true);

            //Add checkboxes
            foreach (SelectListItem item in multiSelectList)
            {
                divTag.InnerHtml += String.Format("<div><input type=\"checkbox\" name=\"{0}\" id=\"{0}_{1}\" " +
                                                    "value=\"{1}\" {2} /><label for=\"{0}_{1}\">{3}</label></div>",
                                                    propertyName,
                                                    item.Value,
                                                    selectedValues.Contains(item.Value) ? "checked=\"checked\"" : "",
                                                    item.Text);
            }

            return MvcHtmlString.Create(divTag.ToString());
        }

我这样称呼它:

 <h2>Rights</h2>
    <div>
        @Html.CheckBoxListFor(m=>m.SelectedRights, Model.Rights)
    </div>

它可以正确渲染。但是,所选值不会回发。我该如何解决这个问题?任何人都可以提出一个好的起点吗?

更新: 我认为添加更多细节可能会更好,因为这件事可能有多个问题。

复选框的 ID 像“SelectedRights_6”一样出来。这是我目前正在使用的 ViewModel。

 public class RoleSingleViewModel : BaseEntitySingleViewModel
    {
    public override int ListViewColSpan
    {
        get { return 6; }
    }

    public string Name {get;set;}
    public string Description {get;set;}

    public IEnumerable<SelectListItem> Sites {get;set;}
    public int SiteId{get;set;}
    public string SiteText{get;set;}
    public override string TypeName
    {
        get { return "Role"; }
    }

    public MultiSelectList Rights { get{return new MultiSelectList(AllRights, "Key", "Value", SelectedRights);}}
    public List<KeyValuePair<int, string>> AllRights { get; set; }
    public List<KeyValuePair<int, string>> SelectedRights { get; set; }
}

另外,控制器上的更新方法也是如此。我在抛出异常的行上设置了一个断点并检查了 updateItem。未填写 Rights、AllRights 和 SelectedRights 的值(我猜这是预期的行为)。我在想我的问题可能与我的 ViewModel 的结构有关。我应该如何改变它?

[HttpPost]
public ActionResult Edit(RoleSingleViewModel updateItem)
    {
      throw new NotImplementedException();

    }
4

2 回答 2

0

我发现我需要初始化一个集合才能绑定结果,即必须在绑定之前初始化 For 属性。模型绑定器不会创建集合,但如果您已经定义了集合,它将添加项目:

在你的模型上

private IEnumerable<int> checkedItems = new List<int>();

public IEnumerable<int> CheckedItems
{ 
    get { 
        return this.checkedItems ;
    }

    set {
        this.checkedItems  = value;
    }
}

在剃刀视野中

@Html.CheckBoxListFor(CheckedItems, ...)
于 2012-11-25T00:58:31.343 回答
0

从复选框中删除ID 属性。当它将选定的值(仅)发布到服务器时,它将是整数或字符串数​​组(我从未用字符串测试过)。所以你的模型/参数应该有相同的属性名称(它应该是一个数组)。

于 2012-08-08T03:09:48.260 回答