2016-06-07 30 views

回答

0

DotVVM中的GridView控制器目前不支持spanned header列。但是,您可以简单地扩展控件以支持此功能。

public class CustomGridView : GridView 
{ 

    [MarkupOptions(AllowBinding = false, MappingMode = MappingMode.InnerElement)] 
    public List<GridViewHeaderSpan> HeaderColumnSpans 
    { 
     get { return (List<GridViewHeaderSpan>)GetValue(HeaderColumnSpansProperty); } 
     set { SetValue(HeaderColumnSpansProperty, value); } 
    } 
    public static readonly DotvvmProperty HeaderColumnSpansProperty 
     = DotvvmProperty.Register<List<GridViewHeaderSpan>, CustomGridView>(c => c.HeaderColumnSpans, null); 


    protected override void OnPreRender(IDotvvmRequestContext context) 
    { 
     // let the GridView build the cells as it always do 
     base.OnPreRender(context); 

     if (HeaderColumnSpans != null) 
     { 
      // check that spans don't collide with each other 
      var spans = HeaderColumnSpans.OrderByDescending(s => s.ColumnIndex).ToList(); 
      foreach (var span in spans) 
      { 
       if (spans.Any(s => s.CollidesWith(span))) 
       { 
        throw new DotvvmControlException(this, "Collisions found in the HeaderColumnSpans collection!"); 
       } 
       if (span.ColumnIndex < 0 || span.SpannedColumns <= 1 || span.ColumnIndex + span.SpannedColumns > Columns.Count) 
       { 
        throw new DotvvmControlException(this, "The HeaderColumnSpans contains indexes that are out of range!"); 
       } 
      } 

      // go through all spans, remove the columns, and set the colspan attribute to the <th> elements 
      // we have sorted them by the column index descending, so we don't change indexes of the <th> elements 
      foreach (var span in spans) 
      { 
       var headerRow = Children[0].Children[0]; 

       // set the colspan attribute 
       var firstCell = (HtmlGenericControl)headerRow.Children[span.ColumnIndex]; 
       firstCell.Attributes["colspan"] = span.SpannedColumns.ToString(); 

       // remove the next columns 
       for (var i = span.SpannedColumns - 1; i >= 1; i--) 
       { 
        headerRow.Children.RemoveAt(span.ColumnIndex + i); 
       } 
      } 
     } 
    } 
} 

public class GridViewHeaderSpan : DotvvmBindableObject 
{ 

    public int ColumnIndex 
    { 
     get { return (int)GetValue(ColumnIndexProperty); } 
     set { SetValue(ColumnIndexProperty, value); } 
    } 
    public static readonly DotvvmProperty ColumnIndexProperty 
     = DotvvmProperty.Register<int, GridViewHeaderSpan>(c => c.ColumnIndex, 0); 

    public int SpannedColumns 
    { 
     get { return (int)GetValue(SpannedColumnsProperty); } 
     set { SetValue(SpannedColumnsProperty, value); } 
    } 
    public static readonly DotvvmProperty SpannedColumnsProperty 
     = DotvvmProperty.Register<int, GridViewHeaderSpan>(c => c.SpannedColumns, 2); 


    public bool CollidesWith(GridViewHeaderSpan span) 
    { 
     if (span == this) 
     { 
      // cannot colide with self 
      return false; 
     } 

     // the whole span must be before this one or after this one 
     return (ColumnIndex < span.ColumnIndex + span.SpannedColumns) && (ColumnIndex + SpannedColumns > span.ColumnIndex); 
    } 
} 

可以使用集合中的标记配置它 - 你只要告诉GridView的索引(从零开始)是合并在一起的列,其中合并后的区域应该开始(ColumnIndex),和列数的(SpannedColumns)。

<cc:CustomGridView DataSource="{value: Customers}"> 
    <Columns> 
     <dot:GridViewTextColumn HeaderText="ID" ValueBinding="{value: Id}" AllowSorting="true" /> 
     <dot:GridViewTextColumn HeaderText="Name" ValueBinding="{value: FirstName}" AllowSorting="true" SortExpression="LastName" /> 
     <dot:GridViewTextColumn HeaderText="" ValueBinding="{value: LastName}" /> 
     <dot:GridViewTemplateColumn HeaderText="Controls"> 
      Edit 
     </dot:GridViewTemplateColumn> 
     <dot:GridViewTemplateColumn> 
      Delete 
     </dot:GridViewTemplateColumn> 
    </Columns> 
    <HeaderColumnSpans> 
     <cc:GridViewHeaderSpan ColumnIndex="1" SpannedColumns="2" /> 
     <cc:GridViewHeaderSpan ColumnIndex="3" SpannedColumns="2" /> 
    </HeaderColumnSpans> 
</cc:CustomGridView>