如何冻结 Radgrid MVC 中的列
介绍如何在 Telerik Radgrid MVC 中冻结列,该功能目前在该控件中不可用。
引言
本文的目的是在 RadGrid MVC 中冻结列。目前,RadGrid MVC 中没有此功能,因此我决定自己创建一个。本文演示了在滚动时使 RadGrid 列保持静态的功能。当用户使用水平滚动条导航时,您希望始终使部分列数据可见,这将非常有用。
Using the Code
要启用此网格功能,只需在客户端将控件的“freezeGridColumn
”设置为一个值,该值决定了当您在网格中拖动水平滚动条时将保持静态定位的列数(从最左边的列开始)。
<script type="text/javascript">
function applyFrozenColumns() {
$('#CustomerGrid').freezeGridColumn(1);
}
</script>
<div class="grid">
<%
Html.Telerik().Grid(Model)
.Name("CustomerGrid")
.Columns(columns =>
{
columns.Bound(c => c.Title).Width(80);
columns.Bound(c => c.FirstName).Width(280);
columns.Bound(c => c.LastName).Width(180);
columns.Bound(c => c.Address).Width(180);
columns.Bound(c => c.Suburb).Width(180);
columns.Bound(c => c.State).Width(180);
columns.Bound(c => c.Postcode).Width(180);
columns.Bound(c => c.Email).Width(180);
columns.Bound(c => c.Mobile).Width(180);
columns.Bound(c => c.Telephone).Width(180);
columns.Bound(c => c.Fax).Width(180);
})
.Sortable(sorting => sorting.SortMode(GridSortMode.SingleColumn))
.DataBinding(binding => binding.Ajax().Select("GetCustomers", "Home"))
.Scrollable(scrolling => scrolling.Height(150)).Render();
%>
<% Html.Telerik().ScriptRegistrar().OnDocumentReady("applyFrozenColumns();"); %>
</div>
它是如何工作的?
为了实现冻结列,我们必须首先了解 Radgrid 的渲染方式、其整体结构和行为。如果您使用 Firebug 在 Firefox 中查看 HTML 源代码,您会发现 Radgrid 包含 3 个部分。
- 标题
- Content
- 页脚
我们感兴趣的部分是 Header(页眉)和 Content(内容)。每个部分都包含一个定义网格布局的表。允许页眉和内容在滚动时链接在一起的网格内部锁定机制,仅仅是通过设置每个列的固定宽度来实现的。
如果我们查看内容部分,它使用样式来实现基本的滚动。内容部分包含一个具有固定宽度列的表。如果表超出了其父容器的固定宽度,它将按默认行为自动滚动。
现在我们理解了 Radgrid 滚动背后的基本机制,我们可以实现自己的功能来实现冻结列。以下步骤提供了高层设计以及其工作原理。
步骤 1
禁用内容容器中的默认滚动。为此,我们只需使用 jQuery 来操作内容容器的样式,将“overflow”设置为 hidden,以防止其滚动。
第二步
在内容容器之后插入一个自定义的冻结容器。在冻结容器内,插入一个子冻结容器。目的是创建我们自己的自定义滚动,以实现冻结列功能。父冻结容器将决定滚动多少,而子容器将决定内容容器内表的宽度。
步骤 3
确定有多少列隐藏在内容容器后面。完成此操作后,我们将为隐藏在内容容器后面的列设置滚动。这样做可以最大程度地降低性能成本。
步骤 4
附加到滚动容器的滚动事件。当滚动事件触发时,这就是我们实现功能的地方。
步骤 5
确定当前滚动位置,然后相应地显示表头和表内容列。这是此功能的核心部分,我们检查当前滚动位置,如果它超出了显示列的宽度,则隐藏它,否则显示它。隐藏表格单元格的效果会产生一种滚动的感觉,但实际上只是单元格内部的单元格在隐藏。
技术详情
在 jQuery 中创建一个名为“FreezeGridColumn
”的新函数,以启用冻结列功能。然后确定其绑定行为,无论是服务器绑定还是 Ajax 绑定。对于 Ajax 绑定,我们需要知道 Ajax 请求何时完成。否则,在渲染未完成时我们将获得错误的父宽度。
$.fn.freezeGridColumn = function(frozenColumnsCount) {
if (!$(this).data('tGrid').isAjax()) {
initFreezeColumns($(this), frozenColumnsCount);
}
else {
$(this).ajaxStop(function() {
initFreezeColumns($(this), frozenColumnsCount);
});
}
};
在 RadGrid 中插入自定义滚动处理以实现冻结列功能。首先,我们需要通过将样式设置为“overflow hidden”来禁用默认滚动。其次,我们在下方创建冻结容器来处理自定义滚动。
function createScrollContainer() {
//disable grid default scrolling
$(grid).find(".t-grid-content").css("overflow-x", "hidden");
if ($(frozenContainer).length == 0) {
//create controls to handle freeze column scrolling
frozenContainer = $("<div id='gridfrozenContainer' />");
frozenInnerContainer = $("<div id='gridfrozenInnerContainer' />");
}
$(frozenContainer).css("height", "17px").css("overflow",
"scroll").css("width", "100%");
$(frozenInnerContainer).css("height", "17px").css("width",
$(gridContentTable).width());
$(frozenContainer).append($(frozenInnerContainer));
$(frozenContainer).insertAfter('.t-grid-content');
}
确定内容容器中有多少列不可见。
//get how many columns are not visible behind the content container
function getHiddenColCount() {
var visibleWidth = grid.find("div.t-grid-header").width();
var visibleColCount = 0;
$.each(tableHeaderGroupCol, function(idx, value) {
totalColWidth += getWidth($(value));
if (visibleWidth >= totalColWidth) {
visibleColCount = idx;
}
});
hiddenColCount = totalColCount - visibleColCount;
}
执行冻结功能。
for (i = frozenColumnsCount; i <= hiddenColCount; i++) {
totalColWidth += columnWidthArr[i - 1];
var showCol = (scrollPos < totalColWidth);
$(tableHeaderCol).eq(i).children().toggle(showCol);
$(tableHeaderGroupCol).eq(i).toggle(showCol);
$(tableContentGroupCol).eq(i).toggle(showCol);
$(tableHeaderCol).eq(i).toggle(showCol);
$(gridContentTable).find("tbody tr td[cellIndex=" + i + "]").toggle(showCol);
}
浏览器支持
- 在 IE6、IE7、IE8、IE9、Chrome 和 Firefox 中测试
限制
- 冻结列不支持与层次结构网格一起使用
屏幕截图
历史
- 08/08/2011
- 修复了 bug - 冻结多列时丢失列
- 09/05/2011
- 修复了最后一列显示不正确的问题
- 05/05/2011
- 支持浏览器 Internet Explorer 8、Internet Explorer 9