自定义 ASP.NET MVC“渲染表” helper,如何添加一些额外的功能?
所以我正在制作一个自定义的 html 帮助器,它从传入的 IList 中呈现一个表格。它工作正常,但相当基本。我希望能够分配不是从属性名称推断出来的列名称。例如,现在我传入一个名为 Number 的属性,但我想使用 №。
我想我已经通过装饰看到了这一点,我只能假设它使用反射来获取值,但我不太确定如何实现它,但是......
另一件事,我想应用操纵细胞属性的能力。例如,№ 单元格的 colspan
应该为 x,或者任何其他单元格都可以应用一个class
它。我想这也可能属于某种装饰。
最后,我想让一些单元格包含链接,但坦率地说,我不知道如何实现它,除了发送完整的 html 字符串作为要渲染的属性值之外。
因此,我在这里发布我当前版本的代码,希望比我更好的人(那就是你,;))可以给我一些关于如何完成我已经完成的任务的指示上面写的。
更新
小更新,现在传入的 IList 是匿名类型,所以我不确定它如何与装饰一起使用......
public static class ApplicationExtensions {
public static void RenderTable(
this HtmlHelper HtmlHelper,
IList Items) {
RenderTable(HtmlHelper, string.Empty, Items, null, false);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
IList Items,
object Attributes) {
RenderTable(HtmlHelper, string.Empty, Items, Attributes, false);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
IList Items,
IDictionary<string, object> Attributes) {
RenderTable(HtmlHelper, string.Empty, Items, Attributes, false);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
IList Items,
object Attributes,
bool RenderTFoot) {
RenderTable(HtmlHelper, string.Empty, Items, Attributes.ToDictionary(), RenderTFoot);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
IList Items,
IDictionary<string, object> Attributes,
bool RenderTFoot) {
RenderTable(HtmlHelper, string.Empty, Items, Attributes, RenderTFoot);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
string Caption,
IList Items,
object Attributes,
bool RenderTFoot) {
RenderTable(HtmlHelper, Caption, Items, Attributes.ToDictionary(), RenderTFoot);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
string Caption,
IList Items,
IDictionary<string, object> Attributes,
bool RenderTFoot) {
if ((Items != null) && (Items.Count > 0)) {
StringBuilder TableBuilder = (String.IsNullOrEmpty(Caption) ? new StringBuilder() : new StringBuilder().AppendFormat("<caption>{0}</caption>", Caption));
THead(TableBuilder, Items[0].GetType());
TBody(TableBuilder, Items);
if (RenderTFoot) {
TFoot(TableBuilder, Items[0].GetPropertyCount());
};
TagBuilder TagBuilder = new TagBuilder("table");
TagBuilder.MergeAttributes(Attributes);
TagBuilder.InnerHtml = TableBuilder.ToString();
HtmlHelper.ViewContext.HttpContext.Response.Write(TagBuilder.ToString(TagRenderMode.Normal));
};
}
private static void THead(
StringBuilder TableBuilder,
Type Item) {
TableBuilder.Append("<thead><tr>");
foreach (var Property in Item.GetProperties()) {
TableBuilder.AppendFormat("<th>{0}</th>", Property.Name);
};
TableBuilder.Append("</tr></thead>");
}
private static void TBody(
StringBuilder TableBuilder,
IList Items) {
TableBuilder.Append("<tbody>");
foreach (var Item in Items) {
PropertyInfo[] Properties = Item.GetType().GetProperties();
TableBuilder.Append("<tr>");
foreach (PropertyInfo Property in Properties) {
TableBuilder.AppendFormat("<td>{0}</td>", Property.GetValue(Item, null));
};
TableBuilder.Append("</tr>");
};
TableBuilder.Append("</tbody>");
}
private static void TFoot(
StringBuilder TableBuilder,
int Columns) {
TableBuilder.AppendFormat("<tfoot><tr><td colspan=\"{0}\"><input type=\"button\" value=\"◀\" /><input type=\"button\" value=\"▶\" /></td></tr></tfoot>", Columns);
}
private static int GetPropertyCount(
this object Item) {
return Item.GetType().GetProperties().Count();
}
private static IDictionary<string, object> ToDictionary(
this object Object) {
return Object.GetType().GetProperties().ToDictionary(
k =>
(k.Name),
v =>
(v.GetValue(Object, null)));
}
}
它的使用方式如下:
<% Html.RenderTable(Model) // lowest overload... %>
so I have a custom html helper I'm making and it renders a table from an IList
that's passed in. It works fine, but its rather basic. I'd like to have the ability to assign column names that are not inferred from the property name. For example, right now I pass in a property called Number, but I'd like to use №.
I think I've seen this done through decorations, and I can only assume it uses reflection to get the value out, but I'm not quite sure how to pull it off, yet...
Another thing, I'd like to apply the ability to manipulate the attributes of a cell. For example the № cell should have a colspan
of x, or any other cell could have a class
applied to it. I'm thinking that could also fall under a decoration of some kind.
Lastly, I want to have some cells contain links, but quite frankly, I have no idea how to pull it off, short of sending a complete html string as the property value to render.
So, I'm posting my current version of the code here with the hope that someone better than me (that would be you, ;)) could give me some pointers on how to accomplish what I've written above.
UPDATE
Small update, the IList being passed in right now is an anonymous type, so I'm not sure how that plays with decorations...
public static class ApplicationExtensions {
public static void RenderTable(
this HtmlHelper HtmlHelper,
IList Items) {
RenderTable(HtmlHelper, string.Empty, Items, null, false);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
IList Items,
object Attributes) {
RenderTable(HtmlHelper, string.Empty, Items, Attributes, false);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
IList Items,
IDictionary<string, object> Attributes) {
RenderTable(HtmlHelper, string.Empty, Items, Attributes, false);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
IList Items,
object Attributes,
bool RenderTFoot) {
RenderTable(HtmlHelper, string.Empty, Items, Attributes.ToDictionary(), RenderTFoot);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
IList Items,
IDictionary<string, object> Attributes,
bool RenderTFoot) {
RenderTable(HtmlHelper, string.Empty, Items, Attributes, RenderTFoot);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
string Caption,
IList Items,
object Attributes,
bool RenderTFoot) {
RenderTable(HtmlHelper, Caption, Items, Attributes.ToDictionary(), RenderTFoot);
}
public static void RenderTable(
this HtmlHelper HtmlHelper,
string Caption,
IList Items,
IDictionary<string, object> Attributes,
bool RenderTFoot) {
if ((Items != null) && (Items.Count > 0)) {
StringBuilder TableBuilder = (String.IsNullOrEmpty(Caption) ? new StringBuilder() : new StringBuilder().AppendFormat("<caption>{0}</caption>", Caption));
THead(TableBuilder, Items[0].GetType());
TBody(TableBuilder, Items);
if (RenderTFoot) {
TFoot(TableBuilder, Items[0].GetPropertyCount());
};
TagBuilder TagBuilder = new TagBuilder("table");
TagBuilder.MergeAttributes(Attributes);
TagBuilder.InnerHtml = TableBuilder.ToString();
HtmlHelper.ViewContext.HttpContext.Response.Write(TagBuilder.ToString(TagRenderMode.Normal));
};
}
private static void THead(
StringBuilder TableBuilder,
Type Item) {
TableBuilder.Append("<thead><tr>");
foreach (var Property in Item.GetProperties()) {
TableBuilder.AppendFormat("<th>{0}</th>", Property.Name);
};
TableBuilder.Append("</tr></thead>");
}
private static void TBody(
StringBuilder TableBuilder,
IList Items) {
TableBuilder.Append("<tbody>");
foreach (var Item in Items) {
PropertyInfo[] Properties = Item.GetType().GetProperties();
TableBuilder.Append("<tr>");
foreach (PropertyInfo Property in Properties) {
TableBuilder.AppendFormat("<td>{0}</td>", Property.GetValue(Item, null));
};
TableBuilder.Append("</tr>");
};
TableBuilder.Append("</tbody>");
}
private static void TFoot(
StringBuilder TableBuilder,
int Columns) {
TableBuilder.AppendFormat("<tfoot><tr><td colspan=\"{0}\"><input type=\"button\" value=\"◀\" /><input type=\"button\" value=\"▶\" /></td></tr></tfoot>", Columns);
}
private static int GetPropertyCount(
this object Item) {
return Item.GetType().GetProperties().Count();
}
private static IDictionary<string, object> ToDictionary(
this object Object) {
return Object.GetType().GetProperties().ToDictionary(
k =>
(k.Name),
v =>
(v.GetValue(Object, null)));
}
}
And it's used like so:
<% Html.RenderTable(Model) // lowest overload... %>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可能想查看 Html.Grid 来自 ASP.NET MVC 3 RC2。它应该比编写自己的助手容易得多。
You might want to have a look at Html.Grid from ASP.NET MVC 3 RC2. It should be much easier than writing your own helper.
“所以我不确定它如何与装饰一起发挥作用……”
事实并非如此。您将无法从匿名者那里获取元数据。
" so I'm not sure how that plays with decorations..."
It doesn't. You won't be able to get metadata off of an anon.