3

我正在创建一个扩展 WebControl 的自定义控件。此 Web 控件允许使用者在标记中定义列的集合,如下所示:

<Custom:CustomGrid>
<Columns>
    <Custom:DataColumn HeaderText="FirstName" />
    <Custom:DataColumn HeaderText="LastName" />
</Columns>

并将 IEnumerable 放在 DataSource 属性中,然后将其呈现到表中。该控件还允许分页。DataSource 中的 IEnumerable 是完整列表,我一次显示列表的一页。我已经将当前页面、每页的行数等保存到视图状态。我是否也应该将完整列表放入视图状态?也许会话?这个列表可能会变得有点庞大。也许使用随机密钥保存在会话中,该密钥保存在视图状态中?这里的最佳做法是什么?

编辑:我认为强制 IEnumerable 中的所有类型都可序列化是不正确的。这公平吗?那么我需要将数据源复制到其他数据结构中进行序列化吗?

编辑 2:即使我确实使用基本控件而不是实现 RenderChildControls,我也需要实现 CreateChildControls,但我仍然需要将数据保存在某个地方,还是我错过了基类的要点?

4

2 回答 2

2

事实上,并不是所有的IEnumerable实例都是可序列化的。

如果查询运行起来很便宜,我不会保留整个数据集,而只是针对不同的页面或排序顺序的更改再次运行查询。

如果您将数据置于视图状态中,您最终会得到巨大的页面。如果您没有很多用户,会话状态可能是可以接受的,但是具有大量用户的大型数据集将无法很好地扩展。如果我将一百万行绑定到您的控件怎么办?或者,如果您的控件用于转发器并在页面上显示 100 次怎么办?

你确定你需要持久化数据吗?这不是过早优化是吗?

请记住,您的控件是一个 UI 组件。视图状态应该包含足够的信息来维持 UI 状态。状态更改(例如:切换到不同的结果页面)是您的控件应将责任转交给数据源的事情。

看看好旧的GridView。它会显示你给它的东西并记住它。如果您正在使用分页,那么它会引发一个事件,说“用户已更改页面;给我第 x 页数据”。对我来说,这是 UI 控件的最佳实践。

于 2012-12-03T10:07:54.697 回答
0

为了实现数据绑定控制,最好使用旨在执行此类任务的基类。例如,在 ASP.NET 中存在 CompositeDataboundControl,它可以用作实现自定义数据绑定控件的基类。我可以建议查看以下 Dino Esposito 文章:http: //msdn.microsoft.com/en-us/library/aa479016.aspx

基本上,如果您创建像 ASP.NET gridview 这样的控件,那么它将值存储在视图状态中。更清楚地说,它是创建在视图状态中保存分配值的 DataRow 控件的数量。在回发期间,它重新创建相同数量的行,并从视图状态恢复值。如果您将仅保存数据源,例如在会话中不使用视图状态,那么您将需要在每次回发期间将数据重新绑定到您的网格。因此,如果您创建类似于 gridview 的服务器控件,那么 Dino Esposito 帖子中描述的方法将非常有用,因为它展示了如何创建类似于 ASP.NET Server GridView 控件的控件。

于 2012-11-23T18:43:46.500 回答