asp.net-mvc-3 – Telerik MVC网格,在运行时从集合或字典中使用动态列

前端之家收集整理的这篇文章主要介绍了asp.net-mvc-3 – Telerik MVC网格,在运行时从集合或字典中使用动态列前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在过去几天搜索之后,我正式陷入困境.我正在研究将对象绑定到Telerik MVC 3 Grid,但问题是它需要动态创建的列(不是自动生成的).其中三列是已知的,其他列是未知的,这是棘手的部分.基本上,它可以像这些例子:

KnownColumn1 | KnownColumn2 | UnknownColumn1 | KnownColumn3
KnownColumn1 | KnownColumn2 | UnknownColumn1 | UnknownColumn2 | UnknownColumn3 | KnownColumn3
等等

因为我将未知列放在列表中(我也尝试过字典,所以我可以获取列名),这在绑定时对我来说很复杂.我的代码如下:

模型(可以有零到几百行,但是这个模型在List类型的视图模型中,也可以有0到20个动态添加的列)

  1. public class VendorPaymentsGLAccount
  2. {
  3. public string GeneralLedgerAccountNumber { get; set; }
  4. public string GeneralLedgerAccountName { get; set; }
  5. public string DisplayName { get { return string.Format("{0} - {1}",GeneralLedgerAccountNumber,GeneralLedgerAccountName); } }
  6. public Dictionary<string,double> MonthAmount { get; set; }
  7. public double Total { get { return MonthAmount.Sum(x => x.Value); } }
  8. public List<string> Columns { get; set; }
  9. public List<double> Amounts { get; set; }
  10.  
  11. public VendorPaymentsGLAccount() { }
  12. }

查看(注释掉的部分试图使用字典)

  1. <fieldset>
  2. <legend>General Ledger Account Spend History</legend>
  3. @if (Model.VendorPaymentsGLAccounts != null)
  4. {
  5.  
  6. <br />
  7. @(Html.Telerik().Grid(Model.VendorPaymentsGLAccounts)
  8. .Name("Grid")
  9. .Columns(columns =>
  10. {
  11. columns.Bound(gl => gl.DisplayName).Title("General Ledger Account").Width(200).Filterable(false).Sortable(false);
  12.  
  13. //foreach (var month in Model.VendorPaymentsGLAccounts[0].MonthAmount)
  14. //{
  15. // //columns.Bound(gl => gl.MonthAmount[month.Key.ToString()].ToString()).Title(month.Key.ToString()).Width(100).Filterable(false).Sortable(false);
  16. // //columns.Template(v => Html.ActionLink(v.VoucherID,"VoucherSummary",new { id = v.VoucherID,bu = v.BusinessUnitID,dtt = v.InvoiceDate.Ticks })).Title("Voucher").Width(100);
  17. // columns.Template(gl => Html.ActionLink(gl.MonthAmount[month.Key.ToString()].ToString(),"VoucherSummary")).Title(month.Key.ToString()).Width(100);
  18. //}
  19.  
  20. for (int i = 1; i <= (Model.VendorPaymentsGLAccounts[0].Columns.Count() - 1); i++)
  21. {
  22. string colTemp = Model.VendorPaymentsGLAccounts[0].Columns[i - 1];
  23. columns.Template(gl => gl.Amounts[i - 1]).Title(colTemp).Width(100);
  24. }
  25.  
  26. columns.Template(gl => String.Format("{0:C}",gl.Total)).Title("Total");
  27. })
  28. .Sortable()
  29. .Pageable()
  30. .Filterable()
  31. .Footer(true))
  32. }
  33. else
  34. {
  35. <br />
  36. @:There are no records that match your selected criteria.
  37. }
  38. </fieldset>

使用字典方法,我能够使用正确的标题文本正确生成列,但列的值(在我的测试中只有2列)是相同的.有人能帮忙吗?这似乎是一个古怪的问题.只是想弄清楚如何正确地做到这一点.

更新:这是使用字典方法显示问题的屏幕截图.列标题正确,但两个动态列的值相同.

解决方法

使用带有Telerik网格控件的动态定义列可能很棘手.但在你的情况下,它主要是一个典型的闭包陷阱.

在以下循环中,编译器将绑定gl =>的每个实例. gl.Amounts [i – 1]到变量i并稍后评估它:

  1. for (int i = 1; i <= (Model.VendorPaymentsGLAccounts[0].Columns.Count() - 1); i++)
  2. {
  3. string colTemp = Model.VendorPaymentsGLAccounts[0].Columns[i - 1];
  4. columns.Template(gl => gl.Amounts[i - 1]).Title(colTemp).Width(100);
  5. }

实际上,它是在循环结束后进行评估的.所以我将始终拥有导致循环完成的值.

修复是使用临时变量:

  1. for (int i = 1; i <= (Model.VendorPaymentsGLAccounts[0].Columns.Count() - 1); i++)
  2. {
  3. string colTemp = Model.VendorPaymentsGLAccounts[0].Columns[i - 1];
  4. int columnIndex = i - 1;
  5. columns.Template(gl => gl.Amounts[columnIndex]).Title(colTemp).Width(100);
  6. }

猜你在找的asp.Net相关文章