在Dotvvm GridView中,是否可以为2列或更多列提供一个标题?你能举个例子吗?
答案 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>