2

MVCContrib Grid 中优雅的动作语法为我们提供了Empty()方法。但是,默认行为MvcContrib.UI.Grid.GridRenderer<T>.RenderHeader()是在网格为空时隐藏表格列标题。当数据不存在且不需要重大重构时,有没有办法显示标题?

现在我听说默认隐藏标题并硬编码一些东西,但这对我来说并不酷。

顺便说一句,这就是幕后发生的事情(in 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();
}
4

5 回答 5

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 在客户端操作表格,但请注意。

于 2011-04-11T17:10:39.940 回答
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();
    }
于 2011-06-07T19:32:36.190 回答
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();
}

…</p>

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;

…</p>

/// <summary>
/// Initializes a new instance of the <see cref="CrmHtmlTableGridRenderer&lt;T&gt;"/> class.
/// </summary>
/// <param name="engines">The engines.</param>
public CrmHtmlTableGridRenderer(ViewEngineCollection engines)
    : base(engines)
{
    _engines = engines;
}
于 2010-08-03T21:07:25.093 回答
0

您不能只注释掉检查以查看它是否应该呈现标题。我是否遗漏了某些内容,或者您​​是否希望它始终显示标题?

如果是这样,请注释掉该行。

//if(! ShouldRenderHeader()) return false;

我没有查看所有代码,但从您的代码片段看来应该可以。

于 2010-08-03T05:27:10.620 回答
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();
}
于 2014-06-06T16:31:13.487 回答