2

我正在寻找一个针对.NET 的数据感知网格,该网格已针对底层数据集的重复更改进行了优化。我将举一个例子来说明我在这种情况下优化的意思,因为几乎所有网格都允许您更改数据源。但是回到 OCX 时代,改变数据源给数据感知网格带来了问题。

此数据感知数据驱动网格不得使用整数行句柄。它必须使用 GUID 行句柄。这是这个网格最重要的要求。

底层数据集的每一行都被分配了一个 GUID rowHandle,而不是一个整数,并且无论数据行如何排序或分组,数据行的 GUID rowHandle 都保持不变,并且可以通过其 rowHandle 立即检索数据行。

当当前获得焦点的行的 GUID 与最近获得焦点的行的 GUID 不同时,将触发网格的FocusedRowChanged事件。 [编辑:在使用整数行句柄的网格中,通常情况下,当数据源更改时,FocusedRowChanged 事件不会触发,因为focused-row-position 没有更改;例如,焦点在数据源更改前的第一行,焦点在数据源更改后的第一行;即使基础行数据完全不同,整数行句柄也是相同的。]

我希望网格的行为是真正的数据感知和数据驱动;例如

Grid.GroupByColumnNames = {"customername","city"};
Grid.Groups["customername"].ExpandedValues = {"Acme Widgets", "Foo Industrial"};
Grid.Groups["city"].ExpandedValues = {"New York","Miami"};

现在,如果我清除上面网格的基础数据集并用另一个数据集替换它的数据源,该数据源也有 customername 和 city 列,并在该列中包含值 Acme Widgets 和 Foo Industrial,网格将按 customername 对新数据集进行分组和城市列,并展开这些公司(如果 PreserveGroupingsWhenDataSetChanges 标志设置为 True)。

4

1 回答 1

0

这个问题有一些根本性的错误,这就是为什么几个月后没有人提供一个好的答案。即使您的数据的主键是 GUID,它也不能证明控件的行句柄是 GUID。事实上,这是一个非常糟糕的主意。GUID 是 128 位(16 字节),而 int 通常是 32 位 - 但比位数更重要(比如在某些环境中是 64 位)是 int 操作是原子的,这意味着您可以读取/写入 int 而无需锁定线程和更高的性能。因此 GUID 具有更高的内存占用和更高的处理成本(读取/写入将是多个操作)。

因此,实际上任何控件都应该在视觉上使用快速/精简代码,并且在需要获取主键或其他数据位时仅引用数据源。

我对网格的体验和思考

我碰巧喜欢用于 winforms 的 DevExpress 控件,并且还使用它们的数据层组件 XPO。然而,有多个组件供应商具有相似的控件和数据层(它们通常都共享将行句柄与数据主键分离的特性)。

在 DevExpress 中,他们有一个出色的网格,它是数据感知的,并为您提供了大量事件,以供您参与各种可能的更改。

XPO 数据层可以使用任何东西作为主键,包括 int 或 Guid。由于能够从远程机器或离线数据插入主键,我和许多其他开发人员一起使用 Guids(我不能说我曾经负责过一个表中包含超过 20 亿条记录的数据库,但是也许你是)。

虽然我的数据的主键可能是 GUID,但行句柄仍然是整数。这在幕后将比 Guid 快得多。但是,它们仍然提供了一堆在可视索引、行句柄和数据源索引之间来回切换的方法,以及一些通过行句柄获取底层数据源行的方法。这在提供行句柄(不是数据主键)的许多控件事件中很有用,您只需使用一行代码通过行句柄获取数据源记录。

此外,一般来说,如果您使用基于字符串的索引器访问集合,如上面的伪代码中所示,组件只需在List.IndexOf()后台执行一种调用,然后将其作为 int 索引传递给索引器。因此,您实际上仍在幕后使用基于 int 的索引。即使某些组件公司将 GUID 用于行句柄,他们也会将这些 GUID 放入幕后的哈希集或字典中,以查找要实际使用的 int 索引。因此,无论如何它都只是 int 之上的层,所以它们只是将其抽象化,并让您在需要时在代码中实现这种东西(而不是将其构建到组件库中)。

推荐

最重要的是,我认为您可以使用 DevExpress Grid 完成上述所有操作,但必须放弃 GUID 行句柄并稍微改变您的策略。如果您的应用程序需要这种反向查找,您可能需要构建自己的 GUID 以将行索引作为哈希集或字典。如果所有行句柄始终是 GUID,但仍为您提供 GUID 和行句柄之间的正向和反向转换,这可以避免性能问题。

于 2011-11-17T23:34:11.740 回答