2010-08-03 38 views
2

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

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

顺便说一句,这是什么是引擎盖下发生(在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(); 
} 

回答

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&lt;T&gt;"/> class. 
/// </summary> 
/// <param name="engines">The engines.</param> 
public CrmHtmlTableGridRenderer(ViewEngineCollection engines) 
    : base(engines) 
{ 
    _engines = engines; 
} 
0

你就不能注释掉检查,看它是否应该呈现的头。我错过了什么,或者你是否希望它始终显示标题?

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

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

我没有看过所有的代码,但从你的代码片段看起来应该工作。

+1

我不想禁用MVCContrib默认功能......我们需要寻找正规的扩展点...... – rasx 2010-08-03 18:10:38

+0

我现在看到...我已经有一个'正式的可扩展性'工作;它是子类'GridRenderer '---我所要做的(似乎)是重写'RenderHeader()'... – rasx 2010-08-03 18:24:34

5

您可以覆盖HtmlTableGridRenderer类的ShouldRenderHeader()方法。

public class AlwaysRenderHeaderRenderer<T> 
    : HtmlTableGridRenderer<T> where T : class 
{ 
    protected override bool ShouldRenderHeader() 
    { 
     return true; 
    } 
} 

<%= Html.Grid(Model).RenderUsing(new AlwaysRenderHeaderRenderer<TypeOfModel>()) %> 

这种方法的一个副作用是当网格为空时,将会呈现一个空的表体而不是消息。提供给Empty()的任何文本都将被忽略。这对我来说不是一个问题,因为我用JavaScript来操纵客户端的表格,但是会被警告。

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(); 
    } 
0

David'sBrant's答案的组合:

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(); 
}