2017-02-02 3 views
1

子モデルのリストのコンテキストでDropDownListForの値をバインドする方法はありますか?子モデルのリストのコンテキストでDropDownListForが値をバインドしない

現在、子モデルのリストがループしている親モデルがある場合、DropDownListFor HtmlHelperは値をバインドしません。

Model.cs

using System; 
using System.Web.Mvc; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 

namespace HelloWorldMvcApp 
{ 
    public class Model 
    { 
     public int? SelectedValue { get; set; } 

     public List<Value> Values { get; set; } 

     public IEnumerable<SelectListItem> Fields 
     { 
      get 
      { 
       return new[] 
       { 
        new SelectListItem { Text = "1", Value = "1" }, 
        new SelectListItem { Text = "2", Value = "2" }, 
        new SelectListItem { Text = "3", Value = "3" } 
       }; 
      } 
     } 

     public Model() 
     { 
      Values = new List<Value>(); 
     } 
    } 

    public class Value 
    { 
     public int SelectedValue { get; set; } 

     public string Name { get; set; } 
    } 
} 
:これはここにコピーフィドルのコードが https://dotnetfiddle.net/RB4UVc

次のとおりです。

私はこれを説明するためにdotnetfiddleのケースを作成しました

HomeController.cs

using System; 
using System.Web.Mvc; 
using System.Collections.Generic; 

namespace HelloWorldMvcApp 
{ 
    public class HomeController : Controller 
    { 
     [HttpGet] 
     public ActionResult Index() 
     { 
      var model = new Model(); 

      model.SelectedValue = 2; 
      model.Values.Add(new Value { SelectedValue = 3, Name = "John Doe" }); 

      return View(model); 
     } 
    } 
} 

Index.cshtml

@model HelloWorldMvcApp.Model 

<h1>Single</h1> 
<p>Value: @Model.SelectedValue</p> 

@Html.DropDownListFor(model => model.SelectedValue, Model.Fields) 

<hr> 

<h1>Collection</h1> 

@foreach(var value in Model.Values) 
{ 
    <p>Value: @value.SelectedValue</p> 

    <p>Name: @Html.TextBoxFor(_ => value.Name)</p> 

    @Html.DropDownListFor(_ => value.SelectedValue, Model.Fields) 
} 

<hr> 

<h1>Indexed Collection</h1> 

@for(var i = 0; i < Model.Values.Count(); i++) 
{ 
    <p>Value: @Model.Values[i].SelectedValue</p> 

    <p>Name: @Html.TextBoxFor(model => model.Values[i].Name)</p> 

    @Html.DropDownListFor(model => model.Values[i].SelectedValue, Model.Fields) 
} 

最初は正しくバインド正常値を使用している、第二子の集まりだろうモデル。わかるように、TextBoxForは値を正しくバインドすることができます。

ここで何か間違っているのですか、またはこの問題の回避策がありますか? (手作業の横に<select>要素があります)

サイドノート:これは、子モデルの配列を一括して保存する必要があることを考慮して、これをループのコンテキストで具体的に調べています。

+1

あなたの質問にコードを含める必要があります(リンクが死んで問題を無用にしてしまい、私が訪問したときに機能しないことさえあります)。問題は[この回答]で説明されています(http://stackoverflow.com/questions/37407811/mvc5-razor-html-dropdownlistfor-set-selected-when-value-is-in-array/37411482#37411482) –

+0

@ StephenMueckeここでコピーしたコードを編集しました。 dotnetfiddleは手に取ってからそれを実行する利点があったが、私はあなたのポイントを参照してください。また、あなたがそこで見つけた素晴らしい答え!それはハックだが、うまくいくかもしれない。 – Erick

+1

できますか?それは、そして私の答え:)。副作用として、あなたが提出したときに 'foreach'loopオプション(質問ではなく、フィドルではありません)は動作しません - 参照[この回答](http://stackoverflow.com/questions/30094047/html-table- to-ado-net-datatable/30094943#30094943)説明については –

答えて

0

まず、コレクションループ内の現在のインデックスを取得するために値を手動で増やす必要はありません。 「選択があり、第二に

(私はそのコードをテストしていませんでした、ご注意ください。)

@for(int i = 0; i < Model.Values.Count(); i++) 
{ 
    <p>Value: @Model.Values[i].SelectedValue</p> 

    <p>Name: @Html.TextBoxFor(model => model.Values[i].Name)</p> 

    @Html.DropDownListFor(model => model.Values[i].SelectedValue, Model.Fields) 
} 

:あなたはそれではなく、そのような「foreachの」ループ「のため」と書くことができます'SelectListItemオブジェクトのブール値。ページの読み込み時に選択したいオブジェクトに対して、これをtrueに設定してみてください。

+0

forループを考えて、私はこれを本当に認識していました。'DropDownListFor'は、forかforeachの内部にあるかどうかにかかわらず、バインディングに変更はありません。 さらに、SelectedValueの問題は、合計30個のカテゴリのサブモデルがあり、メモリに合計900個のリスト要素がある場合です。このような些細な使用のために、メモリ使用量が大幅に増加します。小さな用途では、これは実際には非常に便利です。 – Erick

+0

@Erick申し訳ありませんが、私が問題を理解しているかどうかはわかりません。あなたは実際のアイテムのコレクションをモデル化したいと言っていますか? – jdurc

+0

SelectListItemの 'Selected'値を使用することをお勧めします。同じリストに複数のドロップダウンがある場合は、同じリストにあるすべてのものをバインドします。したがって、「選択済み」を使用することはできません。また、各ドロップダウンの前にその値をリセットする必要があります。それをリセットしないと、もう1つの方法はドロップダウンごとに異なるコピーを作成することです。したがって、30個の選択肢のリストを持つ30個のドロップダウンがある場合、メモリー内に合計900個のSelectListItemオブジェクトがあります。それは大きなものではない。 – Erick

関連する問題