2010-08-03 68 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(); 
} 
相關問題