あなたが達成しようとしているかのいずれかの詳細と具体的な例を提供していません。あなたはあなたが持っている問題を解決するためにこれまでに試したソースコードを提供していません。次回はStackOverflowの質問をしてください。あなたの質問をより意味深くし、特定の問題に集中させるためにしてください。
とにかく、ここに例があります。値で、このビューモデルを投入し、うまくいけば、POSTアクションでビューで選択された値を取得します
public class MyViewModel
{
public IEnumerable<string> SelectedValues { get; set; }
public IEnumerable<SelectListItem> Values { get; set; }
}
とコントローラ:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
SelectedValues = new[] { "1", "3" },
Values = new[]
{
new SelectListItem { Value = "1", Text = "item 1" },
new SelectListItem { Value = "2", Text = "item 2" },
new SelectListItem { Value = "3", Text = "item 3" },
}
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
// model.SelectedValues will contain the ids of items that were checked
// in the checkbox list
}
}
とあなたがビューモデルを定義していると仮定してみましょうビュー:
@model MyViewModel
@using (Html.BeginForm())
{
@Html.CheckBoxListFor(x => x.SelectedValues, Model.Values, null)
<button type="submit">OK</button>
}
OK、これまで良好でした。最後の部分はこのCheckBoxListFor
ヘルパーを実装しようとすることです。明らかに、あなたの特定の要件や状況に応じて、これを行うための多くの可能な方法があります(回答の冒頭で私の発言を参照してください)。
public static class HtmlExtnsions
{
public static IHtmlString CheckBoxListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> selectList,
object htmlAttributes
)
{
var name = ExpressionHelper.GetExpressionText(expression);
string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
var values = GetModelStateValue(htmlHelper.ViewData, fullHtmlFieldName, typeof(string[]));
if (values == null)
{
values = htmlHelper.ViewData.Eval(fullHtmlFieldName);
}
if (values != null)
{
var collection =
from object value in values as IEnumerable
select Convert.ToString(value, CultureInfo.CurrentCulture);
var hashSet = new HashSet<string>(collection, StringComparer.OrdinalIgnoreCase);
var list = new List<SelectListItem>();
foreach (var item in selectList)
{
item.Selected = ((item.Value != null) ? hashSet.Contains(item.Value) : hashSet.Contains(item.Text));
list.Add(item);
}
selectList = list;
}
var sb = new StringBuilder();
foreach (var item in selectList)
{
var checkbox = new TagBuilder("input");
checkbox.Attributes["type"] = "checkbox";
checkbox.Attributes["name"] = fullHtmlFieldName;
checkbox.Attributes["value"] = item.Value;
checkbox.GenerateId(fullHtmlFieldName);
if (item.Selected)
{
checkbox.Attributes["checked"] = "checked";
}
sb.Append(checkbox.ToString(TagRenderMode.SelfClosing));
sb.Append(item.Value);
}
return new HtmlString(sb.ToString());
}
private static object GetModelStateValue(ViewDataDictionary viewData, string key, Type destinationType)
{
ModelState modelState;
if (viewData.ModelState.TryGetValue(key, out modelState) && modelState.Value != null)
{
return modelState.Value.ConvertTo(destinationType, null);
}
return null;
}
}
申し訳ありませんが、私の質問はとても曖昧だったが、あなたの答えのためのおかげで、私はすでにそこから多くのことを学びました。だからここにあなたが始めることができ、単にいくつかのサンプル実装です。特に私はTagBuilderやhtmlHelper.ViewData.Evalについて知らなかった。 – zod
@zod、ASP.NET MVCのソースコードを見ていないのですか?標準ヘルパーがどのように実装されているかを知るには、そうすることをお勧めします。フレームワークの理解を深め、カスタムヘルパーの実装を容易にすることができます。 –
これはすべてのチェックボックスに同じIDを生成しますが、これは間違っているため、その1行を削除しました(とにかくIDが必要ないとは思わない)。また、html属性は使用しませんが、ほとんど必要なくなり、削除されました。そうでなければそれは優れています(私はdiv内のすべてのものをラップし、そのクラスに(ハードコードされています)(おそらく私もIDを与える必要があります)、ラベルのタグに各チェックボックスとテキストのペアを入れます)。どうもありがとう。 – zod