MVCContrib Grid中的优雅Action Syntax为我们提供了Empty()
方法。但是,MvcContrib.UI.Grid.GridRenderer<T>.RenderHeader()
的默认行为是在网格为空时隐藏表列标题。有没有一种方法可以在不存在不需要重大重构的数据时显示标题?
现在我听说默认隐藏标题并硬编码,但这对我来说并不酷。
顺便说一句,这就是幕后发生的事情(在MvcContrib.UI.Grid.GridRenderer<T>
中):
protected virtual bool RenderHeader()
{
//No items - do not render a header.
if(! ShouldRenderHeader()) return false;
RenderHeadStart();
foreach(var column in VisibleColumns())
{
//Allow for custom header overrides.
if(column.CustomHeaderRenderer != null)
{
column.CustomHeaderRenderer(new RenderingContext(Writer, Context, _engines));
}
else
{
RenderHeaderCellStart(column);
RenderHeaderText(column);
RenderHeaderCellEnd();
}
}
RenderHeadEnd();
return true;
}
protected virtual bool ShouldRenderHeader()
{
return !IsDataSourceEmpty();
}
protected bool IsDataSourceEmpty()
{
return DataSource == null || !DataSource.Any();
}
答案 0 :(得分:5)
您可以覆盖ShouldRenderHeader()
类的HtmlTableGridRenderer
方法。
public class AlwaysRenderHeaderRenderer<T>
: HtmlTableGridRenderer<T> where T : class
{
protected override bool ShouldRenderHeader()
{
return true;
}
}
<%= Html.Grid(Model).RenderUsing(new AlwaysRenderHeaderRenderer<TypeOfModel>()) %>
这种方法的副作用是当网格为空时,将呈现空的表体而不是消息。提供给Empty()
的任何文本都将被忽略。这对我来说不是问题,因为无论如何我都在使用JavaScript操作客户端的表,但是要注意。
答案 1 :(得分:4)
从HtmlTableGridRenderer
继承时,您也可以覆盖RenderEmpty
以消除Brant遇到的问题。
protected override void RenderEmpty()
{
RenderHeadStart();
foreach(var column in VisibleColumns())
{
RenderHeaderCellStart(column);
RenderHeaderText(column);
RenderHeaderCellEnd();
}
RenderHeadEnd();
RenderBodyStart();
RenderText("<tr><td colspan=\"" + VisibleColumns().Count() + "\">" + GridModel.EmptyText + "</td></tr>");
RenderBodyEnd();
}
答案 2 :(得分:3)
在自定义网格渲染器(子类GridRenderer<T>
)中,使用以下覆盖:
/// <summary>
/// Renders the <c>table</c> header.
/// </summary>
/// <returns>
/// Returns the negative of the results
/// of <see cref="GridRenderer<T>.IsDataSourceEmpty"/>.
/// </returns>
/// <remarks>
/// The return value of <see cref="GridRenderer<T>.IsDataSourceEmpty"/>
/// in this override has no effect on whether the Grid header is rendered.
///
/// However, this return value is used
/// by <see cref="GridRenderer<T>.Render"/>
/// to run <see cref="GridRenderer<T>.RenderItems"/>
/// or <see cref="GridRenderer<T>.RenderEmpty"/>.
/// </remarks>
protected override bool RenderHeader()
{
RenderHeadStart();
foreach(var column in VisibleColumns())
{
//Allow for custom header overrides.
if(column.CustomHeaderRenderer != null)
{
column.CustomHeaderRenderer(new RenderingContext(Writer, Context, _engines));
}
else
{
RenderHeaderCellStart(column);
RenderHeaderText(column);
RenderHeaderCellEnd();
}
}
RenderHeadEnd();
return !base.IsDataSourceEmpty();
}
...
protected override void RenderEmpty()
{
RenderBodyStart();
WriteNoRecordsAvailable(base.Writer, this._numberOfTableColumns);
RenderBodyEnd();
}
请注意,WriteNoRecordsAvailable()
是我的自定义方法,因此可以忽略它。
最后:
/// <summary>
/// This private member is duplicated
/// in order to override <see cref="GridRenderer<T>.RenderHeader"/>.
/// </summary>
readonly ViewEngineCollection _engines;
...
/// <summary>
/// Initializes a new instance of the <see cref="CrmHtmlTableGridRenderer<T>"/> class.
/// </summary>
/// <param name="engines">The engines.</param>
public CrmHtmlTableGridRenderer(ViewEngineCollection engines)
: base(engines)
{
_engines = engines;
}
答案 3 :(得分:0)
你不能只是注释掉检查,看它是否应该呈现标题。我错过了什么,或者你是否希望它始终显示标题?
如果有,那就注释掉那一行。
//if(! ShouldRenderHeader()) return false;
我没有查看所有代码,但是从您的代码片段看起来应该可以正常工作。
答案 4 :(得分:0)
protected override bool ShouldRenderHeader()
{
return true;
}
// Oddly Render relies on ShouldRenderHeader to return IsDataSourceEmpty
// so RenderItems will always be called.
protected override void RenderItems()
{
if (IsDataSourceEmpty())
RenderEmpty();
else
base.RenderItems();
}
protected override void RenderEmpty()
{
RenderBodyStart();
RenderText("<tr><td colspan=\"" + VisibleColumns().Count() + "\">" + GridModel.EmptyText + "</td></tr>");
RenderBodyEnd();
}