2015-08-27 22 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