在Delphi XE4和Devexpress VCL 13.1.2中粘贴行时,TableView不会更新

时间:2014-06-28 08:53:43

标签: delphi devexpress vcl delphi-xe4

以下是我正在使用的代码段:

var
myTableView: TcxGridDBBandedTableView
rowcount : integer;
.....
.....
procedure ExecutePaste;
begin
    ....
    ....
    ....
    ....
    rowcount := myTableView.DataController.RowCount; //rowcount is 3 here
    myTableView.DataController.Post; //Post the changes into database
    rowcount := myTableView.DataController.RowCount; //rowcount becomes 2 here
    ....
end;

当我右键单击此myTableView中的任何行并从上下文菜单中选择复制行选项时,将调用CopyRow函数,该函数会复制剪贴板中的行。现在,当我再次右键单击另一行并在上下文菜单中选择粘贴选项时,将调用ExecutePaste函数。 ExecutePaste方法使用以下语句将剪贴板数据推送到数据库:

myTableView.DataController.Post;

数据在数据库中很好地发布,但我尝试粘贴的行消失了,我必须刷新屏幕才能看到更新/粘贴的行。调试时我注意到myTableView.DataController.Rowcount是3(我的tableview中有三行,这是正确的),但是一旦我的调试器传递了myTableView.DataController.Post;线,它仍然是2.我不知道为什么我的表视图不清爽?我的表视图也有一些隐藏的列。任何关于此的线索,想法和建议对我都非常有帮助。

1 个答案:

答案 0 :(得分:2)

我假设您正在使用cxGrid的内置粘贴工具,并且您最初在ExecutePaste中显示的代码只是为此处理事件,而问题是&n& #39;由您未能显示的代码引起。您遇到的问题似乎有很多可能的原因,我将按可能性的降序进行讨论。

在你的一条评论中,你说过#34;所以当我选择第二行并复制它时,它会被复制到剪贴板上。现在我选择第3行并在那里执行粘贴。"提到你的网格部分有一些隐藏的列。

Devex网格通常需要您设置KeyField(或类似名称)属性,网格代码使用该属性来唯一标识基础数据集中的行,因此应将其设置为数据集的PK(如果它有一个或一些其他行唯一值 - 在某些情况下,即使你没有为这个属性指定一个值,网格仍然会表现得很明智,但在其他情况下它会赢得,ime。

现在,如果在粘贴操作中复制的网格列恰好包含网格用于唯一标识行的数据集列,那么在ExecutePaste中的.Post之后,网格可能会认为DataController& #39; s节点包含的预测值比预先少一个,如果这样计算它的RowCount,那就是它的值从3下降到2的原因,无论后果是什么 - 屏幕显示的数据减少了具有的唯一行的表观数量。 QED

通过观察.Post之前和之后的行的KeyField值,验证这是否是导致问题的原因应该很简单。如果是原因,只需在执行PasteExecute之前记录您粘贴的行的KeyField值,然后在执行.Post之前将其恢复。

令我困惑的是这个解释是数据集似乎并没有抱怨PK密钥违规。可能的原因可能包括数据集在相关列上没有PK /唯一约束,或者,网格正在使用什么,因为行唯一列实际上不是数据集的PK列。

如果上述内容不允许您查找并修复原因,那么在我看来,除非您获得幸运,并且您的q被cxGrid用户看到,该用户遇到了您的问题且知道如何修复它,你不太可能在SO上得到完整答案。

除非他们自己遇到过,否则没有人可以远远告诉你的是,它是否是由配置问题引起的(主要是,所有网格的属性是否都已正确设置?)或cxGrid代码中的怪癖。坦率地说,最不可能的原因是网格代码中的一个错误,因为Devex网格通过他们庞大的用户群进行了浸泡测试,而且Devex知道他们正在编写代码。

cxGrid是一个非常复杂的组件,IIRCC绕过Delphi的常用机制(我的意思是使用TDataSources等)将数据从相关数据集中获取到网格节点中,并且您的问题受到影响一个严重的情况"我们无法看到你的屏幕"综合征。所以,我认为您必须自己进行调查,如果您无法找到解决方案或满意的解决方案,您最好的选择可能是看看是否可以将其归结为Devex可以复制并帮助你。

为了调查,我从配置结束开始。检查是否已正确设置所有cxGrid的属性。除了KeyField属性之外,Devex网格还具有一些属性,使您可以指定网格与数据集的数据同步的方式(例如,使用数据集的.Locate()方法)。在网格的OLH中查看这些并尝试使用它们。

您的问题可能是由于状态错误导致的问题"您的cxGrid在粘贴操作过程中进入。这就是为什么在我之前的一条评论中,我建议移动数据集的光标 - 网格代码应该注意到这种变化并强制网格通过重新同步数据集来刷新自身以某种方式有望纠正RowCount以及网格显示的内容。我建议的方式(Next + Prior)或两个MoveBy()不会有关闭和重新打开数据集的开销。实际上,根据cxGrid的编码方式,只需立即执行DisableControls后跟EnableControls就足以强制刷新。但是,如果我建议的解释是问题是将KeyField值从一行粘贴到另一行是正确的,那么我不会期望任何这些强制网格更新工作的方法,只能关闭并重新打开数据集。

如果以上都没有找到原因,那么我可以开始从另一端开始调查问题。在Devex源代码中找到.DataController.RowCount的实现,在其中放置一个断点并监视其返回值,然后在执行粘贴操作时密切关注它。当你将它改为2时,你应该能够从那里向上看堆栈(使用View | Debug Windows | Call stack)并找出它为什么会改变到那个值,我想这会得到90%的解决方案或解决方案。

祝你好运!