Dotvvm如何跨GridView中的2个或更多列跨越标题

时间:2016-06-07 15:48:14

标签: dotvvm

在Dotvvm GridView中,是否可以为2列或更多列提供一个标题?你能举个例子吗?

1 个答案:

答案 0 :(得分:0)

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

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>