12

RazorとC#でASP.NETMVC3を使用しています。私はある種のフォームビルダーを作成しているので、次のオブジェクトのコレクションを持つモデルがあります。

public class MyFormField
{
    public string Name { get; set; }
    public string Value { get; set; }
    public MyFormType Type { get; set; }
}

MyFormTypeは、フォームフィールドがチェックボックス、テキストボックス、ファイルアップロードなどのいずれであるかを示す列挙型です。私のエディターテンプレートは次のようになります(コメントを参照):

〜/ Views / EditorTemplates / MyFormField.cshtml

@model MyFormField
@{
    switch (Model.Type)
    {
        case MyFormType.Textbox:
            @Html.TextBoxFor(m => m.Value)
        case MyFormType.Checkbox:
            @Html.CheckBoxFor(m => m.Value)  // This does not work!
    }
}

CheckBoxFor()のラムダ式でをキャスト/ブール値に変換しようとしm.Valueましたが、エラーが発生しました。チェックボックス入力を手動で作成するだけですが、CheckBoxFor()は、複製できない2つのことを実行しているようです。

  1. チェックボックスによって何らかの形で入力される非表示の入力を作成します。これは、モデルバインダーが取得するもののようです。
  2. モデルバインダーが値を適切なプロパティに取得できるように、オブジェクトから名前を生成します。

文字列でCheckBoxFor()を使用する方法、またはその機能を手動で複製してこれを機能させる方法を知っている人はいますか?

4

4 に答える 4

13

1つの方法は、独自のhtmlhelper拡張メソッドを作成することです。

    public static MvcHtmlString CheckBoxStringFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, string>> expression)
    {
        // get the name of the property
        string[] propertyNameParts = expression.Body.ToString().Split('.');
        string propertyName = propertyNameParts.Last();

        // get the value of the property
        Func<TModel, string> compiled = expression.Compile();
        string booleanStr = compiled(html.ViewData.Model);

        // convert it to a boolean
        bool isChecked = false;
        Boolean.TryParse(booleanStr, out isChecked);

        TagBuilder checkbox = new TagBuilder("input");
        checkbox.MergeAttribute("id", propertyName);
        checkbox.MergeAttribute("name", propertyName);
        checkbox.MergeAttribute("type", "checkbox");
        checkbox.MergeAttribute("value", "true");
        if (isChecked)
            checkbox.MergeAttribute("checked", "checked");

        TagBuilder hidden = new TagBuilder("input");
        hidden.MergeAttribute("name", propertyName);
        hidden.MergeAttribute("type", "hidden");
        hidden.MergeAttribute("value", "false");

        return MvcHtmlString.Create(checkbox.ToString(TagRenderMode.SelfClosing) + hidden.ToString(TagRenderMode.SelfClosing));
    }

使用法はCheckBoxForヘルパーと同じです(e.Valueは文字列です)

@Html.CheckBoxStringFor(e => e.Value)
于 2011-08-25T20:07:51.683 に答える
12

ビューモデルにプロパティを追加することもできます。

    public class MyFormField
    {
        public string Name { get; set; }
        public string Value { get; set; }

        public bool CheckBoxValue
        {
            get { return Boolean.Parse(Value); }
        }

        public MyFormType Type { get; set; }
    }

あなたの見解は次のようになります。

@model MyFormField
@{
    switch (Model.Type)
    {
        case MyFormType.Textbox:
            @Html.TextBoxFor(m => m.Value)
        case MyFormType.Checkbox:
            @Html.CheckBoxFor(m => m.CheckBoxValue)  // This does work!
    }
}

例外を回避したい場合は、Boolean.TryParseを使用してください。

于 2011-08-25T20:41:56.097 に答える
4

チェックボックスを使用してください。この簡単な方法で問題なく機能します

@Html.CheckBox("IsActive", Model.MyString == "Y" ? true : false)
于 2015-01-20T20:06:52.227 に答える
0

私もこの問題を抱えていましたが、ビューモデルを変更できませんでした。mdm20sソリューションを試しましたが、コレクションのプロパティでは機能しないと思いました(ネイティブのhtmlヘルパーのように名前とIDにインデックスを追加しません)。これを克服するには、代わりにHtml.CheckBoxを使用できます。適切なインデックスが追加され、チェックボックスの値を自分で渡すことができます。

本当に式を使用したい場合は、いつでもmdm20sに似たラッパーを作成できますが、TryParse以降のすべてを。に置き換えます return Html.CheckBox("propertyName", isChecked)。もちろん、追加する必要もありusing System.Web.Mvc.Htmlます。

于 2012-08-16T01:16:36.407 に答える