2015-08-27 25 views
0

我有一個視圖,其中包含相當多的select元素(形式爲@Html.DropDownList@Html.DropDownListFor)。問題在於它們以類似table的方式排列,並且雙重索引(行數和列數根據數據而變化)。在動態大小的「2D陣列布局」中選擇Html.DropDownListFor中的值

只可能使用單索引屬性/域綁定到DropDownListFor助手的選擇價值,我需要改變屬性的數量,所以我不知道:

是否有ASP.NET MVC方式獲取控制器中的選定值?

也就是說,我現在將使用jQuery來構建一些(可能是JSON)數據以手動發送到控制器。但首先,我想知道是否有別的東西,我可以試試:)

示例項目:查看:

@model DropDownMatrixTest.Models.MatrixViewModel 

@using (Html.BeginForm("Foo", "Home", FormMethod.Post)) 
{ 
    <table> 
    <tbody> 
     @for (int i = 0; i < 10; i++) 
     { 
     <tr> 
      <td>@i-th row:</td> 
      @for (int j = 0; j < 4; j++) 
      { 
      <td> 
       @Html.DropDownListFor(m => m.SelectedValues[@i, @j], 
       Model.Foos.Select(x => new SelectListItem 
       { 
        Text = x.Text, 
        Value = x.Id.ToString() 
       })) 
      </td> 
      } 
     </tr> 
     } 
    </tbody> 
    </table> 
    <button type="submit">Submit</button> 
} 

視圖模型:

public class MatrixViewModel 
{ 
    public IEnumerable<Foo> Foos { get; set; } 
    public int[,] SelectedValues { get; set; } // I know this wouldn't work 
} 

控制器方法:

public ActionResult Index() 
{ 
    MatrixViewModel vm = new MatrixViewModel 
    { 
    Foos = Enumerable.Range(1, 10).Select(x => new Foo { Id = x, Text = "Foo " + x }) 
    }; 
    return View(vm); 
} 

[HttpPost] 
public ActionResult Foo(MatrixViewModel vm) 
{ 
    // Here is where I'd like to get the selected data in some form 
    return View("Index", vm); 
} 

回答

1

創建視圖模型來表示你的表/矩陣結構

public class CellVM 
{ 
    public int SelectedValue { get; set; } 
} 
public class RowVM 
{ 
    public RowVM() 
    { 
     Columns = new List<CellVM>(); 
    } 
    public RowVM(int columns) 
    { 
     Columns = new List<CellVM>(); 
     for(int i = 0; i < columns; i++) 
     { 
      Columns.Add(new CellVM()); 
     } 
    } 
    public List<CellVM> Columns { get; set; } 
} 
public class MatrixVM 
{ 
    public MatrixVM() 
    { 
     Rows = new List<RowVM>(); 
    } 
    public MatrixVM(int columns, int rows) 
    { 
     Rows = new List<RowVM>(); 
     for(int i = 0; i < rows; i++) 
     { 
      Rows.Add(new RowVM(columns)); 
     } 
     // initialize collection with the required number of rows 
    } 
    public List<RowVM> Rows { get; set; } 
    public IEnumerable<SelectListItem> Foos { get; set; } 
} 

在GET方法,初始化的MatrixVM一個新實例,並填充SelectList

MatrixVM model = new MatrixVM(4, 4) 
{ 
    Foos = Enumerable.Range(1, 10).Select(x => new SelectListItem(){ Value = x.ToString(), Text = "Foo " + x }) 
}; 
return View(model); 

並在視圖

@model MatrixVM 
@using (Html.BeginForm()) 
{ 
    <table> 
    <tbody> 
     @for(int r = 0; r < Model.Rows.Count; r++) 
     { 
     <tr> 
      @for(int c = 0; c < Model.Rows[r].Columns.Count; c++) 
      { 
      <td> 
       @Html.DropDownListFor(m => m.Rows[r].Columns[c].SelectedValue, Model.Foos) 
      </td> 
      } 
     </tr> 
     } 
    <tbody> 
    </table> 
    <input type="submit" /> 
} 

邊注:本示例創建一個SelectList控制器是高效且適合創建視圖的控制器,但是如果您編輯現有值,則需要生成新的SelectList並設置Selected原型rty在每次迭代中由於DropDownListFor()在循環中使用時的限制

+0

您好Stephen,感謝您的好建議(再次)!我肯定會嘗試,因爲它比使用jQuery /其他東西更優雅。我會嘗試使用下一個字符串索引器並解析它以獲取座標,但這也更乏味!我在接下來的幾天裏無法測試它,但我確定它應該可以工作,所以請拿我的「接受」;) – InvisiblePanda

+0

如果我在一個小時左右時間內獲得時間,我會將它轉儲到DotNetFiddle中你可以看到它是如何工作的。 –

+0

哦,謝謝,但你不需要那樣做,我明白了「怎麼樣」(老實說,我對自己有點生氣,因爲沒有考慮打破這樣的尺寸;-))。另外,無論如何,我無法打開DotNetFiddle,因爲它由於某種原因被阻塞:/ – InvisiblePanda