2015-10-14 56 views
1

我需要將使用SignalR的Kendo Grid與具有動態列數的Datatable綁定。我怎樣才能做到這一點。我可以直接將Hub中的DataTable對象傳遞給View嗎?我的代碼如下: 查看:如何使用SignalR將具有動態列數的數據表綁定到Kendo UI Grid?

@model System.Data.DataTable 
<script> 
    var TestGridHub = {}; 
    $(function() { 
     TestGridHub = $.connection.TestGridHub; 
    }) 
</script> 
<table><tr><td> 
    @(Html.Kendo().Grid(Model) 
    .Name("TestGrid") 
    .Columns(columns => 
    { 
     foreach (System.Data.DataColumn col in DataTable.Columns) 
     { 
     columns.Bound(col.ColumnName).Title("Name") 
       .ClientTemplate("#=name#"); 
      } 
     }) 
     .DataSource(dataSource => dataSource 
      .SignalR() 
      .PageSize(10) 
      .Transport(tr => tr 
       .Promise("hubStart") 
       .Hub("TestGridHub") 
       .Client(c => c.Read("TestGrid_Read")) 
       .Server(s => s.Read("TestGrid_Read")) 
      ) 
      .Schema(schema => schema 
      .Model(m =>m.Id(p => p.Id)) 
     )) 
     ) 
    </td></tr></table> 

樞紐:

public DataTable TestGrid_Read() 
    { 
     var queryResult = TestRepository.TestGrid_Read_Dynamic(); 
     return queryResult; 
    } 

庫:

public DataTable TestGrid_Read_Dynamic() 
{ 
    using (SqlConnection connection = new SqlConnection(dbContext.Database.Connection.ConnectionString)) 
     { 
      using (SqlCommand cmd = new SqlCommand("SP_TestGrid", connection)) 
      { 
      var dt = new DataTable(); 
      SqlDataAdapter adapter = new SqlDataAdapter(cmd); 
      adapter.SelectCommand.CommandType = System.Data.CommandType.StoredProcedure; 
      adapter.SelectCommand.Parameters.Add(new SqlParameter("@Id", GlobalVaribleDeclarations.Id)); 
      adapter.Fill(dt); 

      return dt; 
      } 
     } 
} 

回答

3

我想它已經比幾個月更因爲你問到這個問題,但這是我一直在修補的東西,並注意到還沒有發佈答案。這就是我所做的一切得到它的工作:

而不是使用Html.Kendo().Grid(Model)的,使用Html.Kendo().Grid<dynamic>()

傳入使用ViewData列定義。我得到了DataTable的一個.Clone(),並將其分配給控制器中的ViewData["columns"],然後在綁定視圖中的網格列時對其進行迭代。

Hub應該將數據作爲DataTable返回。如果你決定使用服務器操作,那麼你會希望你的Read方法接受一個DataSourceRequest參數並返回一個DataSourceResult對象。你需要定義你自己的DataSourceResult類,因此它的Data屬性是一個DataTable。

更新:擴大你如何實現這個

所以電網是建立在多數類似的方式向任何其他,但在劍道格列生成器,你需要通過DataTable的列集合循環:

.Columns(col => 
{ 
    for(var i = 0; i < table.Columns.Count; i++) 
    { 
     if(table.Columns[i].ColumnName == "ID") 
     { 
      col.Bound(table.Columns[i].ColumnName).Hidden(); 
     } 
     else 
     { 
      col.Bound(table.Columns[i].ColumnName); 
     } 
    } 
} 

您可以用類似的方式定義網格的型號:

.Model(mod => 
{ 
    for(var i = 0; i < table.Columns.Count; i++) 
    { 
     if(table.Columns[i].ColumnName == "ID") 
     { 
      mod.Id(table.Columns[i].ColumnName); 
      mod.Field(table.Columns[i].ColumnName, typeof(table.Columns[i].DataType).Editable(false); 
     } 
     else 
     { 
      mod.Field(table.Columns[i].ColumnName, typeof(table.Columns[i].DataType); 
     } 
    } 
} 

但是,即使定義了包含上述數據類型的模型,Kendo HTML助手也不知道如何爲每列選擇編輯器。這可以通過建立列名稱的Stack<string>,按照它們在控制器中的第一列位於堆棧的第一列出現在數據表中的順序,並將其傳遞給視圖來解決。然後把劍道EditorTemplates並修改它們彈出一個名字從堆棧和使用它的編輯器,像這樣:

//DynamicInteger.cshtml 
@model int? 

@{ 
    Stack<string> columnStack = (Stack<string>)ViewData["columns"]; 
    var name = columnStack.Pop(); 
} 

@(Html.Kendo().IntegerTextBoxFor(m => m).Name(name) 
    .HtmlAttributes(new { style = "width:100%" }) 
    .Min(int.MinValue) 
    .Max(int.MaxValue) 
) 

,並更改列定義使用修改EditorTemplates:

//... 
} 
else if (table.Columns[i].DataType == typeof(int)) 
{ 
    col.Bound(table.Columns[i].ColumnName).EditorTemplateName("DynamicInteger"); 
} 

這將導致編輯器被正確分配給每一列,因此您可以獲得格式良好的編輯器,甚至是複雜的編輯器(如DatePicker或DropDownLists),而不是純文本框。

+0

謝謝!你可以用代碼示例來解釋這個解決方案嗎? – giparekh

+0

@giparekh我更新了我的帖子,提供了更多詳細信息 – Sneakster

相關問題