[英]How to use a dynamic model to create a dynamic table
I want to make one table, so I can load a class into it and the table will be automatically generated. 我想制作一张桌子,所以我可以将一个类加载到其中,然后表格将自动生成。
This is what I am looking for, but I have no idea how I can realize this: 这是我想要的,但是我不知道如何实现:
@model dynamic
<table>
<thead>
<tr>
@foreach(var record in model.results)
{
<th>@Html.labelfor(item.indexof(...))</th>
}
</tr>
</thead>
@if (Model.Result.Count() > 0)
{
<tbody>
@for(int i = 0; i < Model.Result.Count(); i++)
{
<tr>
@foreach (var item in Model.Result)
{
<td>@item.indexOf(...)</td>
}
</tr>
}
</tbody>
}
else
{
<p class="errordata">No data found...</p>
}
This is my ViewModel: 这是我的ViewModel:
public class issueModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Color { get; set; }
public string FontColor { get; set; }
public int Count { get; set; }
public string Description { get; set; }
public string Abbreviation { get; set; }
public string icon { get; set; }
public List<dynamic> Result { get; set; }
}
In the "List result" can be different, this is an example class that might be in the result: 在“列表结果”中可以有所不同,这是可能在结果中的示例类:
public partial class someClass
{
[Display(Name = "PID_1")]
public int? someProp_1{ get; set; }
[Display(Name = "PID_2")]
public int? someProp_2{ get; set; }
[StringLength(255)]
public string PermName1 { get; set; }
[StringLength(255)]
public string PermName2 { get; set; }
public string description{ get; set; }
public int? Prioriteit { get; set; }
[StringLength(50)]
public string Login { get; set; }
public int id{ get; set; }
}
I tried to use .indexOf on a dynamic item, but that doesn't work. 我尝试在动态项目上使用.indexOf,但这不起作用。 Is the somehow a way to do this?
是否以某种方式做到这一点? Or do I have to make separate views with separate tables?
还是我必须使用单独的表进行单独的查看?
You need Reflection for this scenario. 在这种情况下,您需要反射。 You should build a new Html Helper.
您应该构建一个新的HTML Helper。 This helper iterate over all public properties of your model, and create a table with that info, then you only need to call helper in your view:
该帮助程序遍历模型的所有公共属性,并使用该信息创建一个表,然后您只需要在视图中调用辅助程序:
Helper Class: 助手类:
namespace System.Web.Mvc
{
public static class TableHelperExtensions
{
public static string BuildTr(object _obj)
{
var properties = _obj.GetType().GetProperties();
var tr = "<tr>";
foreach(var property in properties) {
tr += String.Format("<td>{0}</td>", property.GetValue(_obj));
}
tr += "</tr>";
return (tr);
}
public static string BuildTrHeader(object _obj)
{
var properties = _obj.GetType().GetProperties();
var tr = "<tr>";
foreach (var property in properties)
{
tr += String.Format("<th>{0}</th>", property.Name);
}
tr += "</tr>";
return (tr);
}
public static HtmlString BuildTable(this HtmlHelper helper, object _obj)
{
if(!IsCollection(_obj.GetType())) {
throw new InvalidOperationException("BuildTable helper can be called only on collection object");
}
var tableStart = String.Format(@"<table>
<thead>
{0}
</thead>
<tbody>", BuildTrHeader((_obj as IEnumerable<object>).ElementAt(0)));
var tableBody = String.Empty;
var coll = _obj as IEnumerable<object>;
foreach(var _ in coll){
tableBody += BuildTr(_);
}
var tableEnd = @"
</tbody>
</table>";;
return new HtmlString(tableStart + tableBody + tableEnd);
}
static bool IsCollection(Type type)
{
return type.GetInterface(typeof(IEnumerable<>).FullName) != null;
}
}
}
Example view: 示例视图:
@{
Layout = null;
var objs = new List<object>();
objs.Add(new { a = "Hello", b = "World" });
objs.Add(new { a = "World", b = "Hello" });
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Test</title>
</head>
<body>
@Html.BuildTable(objs)
</body>
</html>
Take a look at ModelMetadata . 看一下ModelMetadata 。 Also look at ModelMetadataProvider and maybe even CustomMetadataProvider.
还要看看ModelMetadataProvider甚至CustomMetadataProvider。
I use these to generically render complete editor dialogs. 我用它们来一般地渲染完整的编辑器对话框。
ModelMetadata metadata = (ModelMetadata)ViewData.ModelMetadata;
ModelMetadata[] properties = metadata.Properties.Where(pm => pm.ShowForEdit && (pm.IsReadOnly || !ViewData.TemplateInfo.Visited(pm))).ToArray();
foreach (TemplateMetadata prop in properties)
{
if (!prop.HideSurroundingHtml)
{
@Html.Label(prop.PropertyName, prop.DisplayName + ((prop.ModelType != typeof(bool) && prop.IsRequired) ? " *" : ""))
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.