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

在Delphi XE4和Devexpress VCL 13.1.2中粘贴行时,TableView未更新,delphi,devexpress,vcl,delphi-xe4,Delphi,Devexpress,Vcl,Delphi Xe4,以下是我正在处理的代码片段: var myTableView: TcxGridDBBandedTableView rowcount : integer; ..... ..... procedure ExecutePaste; begin .... .... .... .... rowcount := myTableView.DataController.RowCount; //rowcount is 3 here myTableView.DataC

以下是我正在处理的代码片段:

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。我不知道为什么我的表视图不刷新?我的表视图也有一些隐藏列。关于这方面的任何线索、想法和建议都会对我非常有帮助。

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

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

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

现在,如果粘贴操作中复制的网格列碰巧包含网格用于唯一标识行的dataset列,那么在ExecutePaste中的.Post之后,网格可能会认为DataController的节点包含的唯一值比之前少一个,如果这就是它计算行数的方式,这就是它的值从3降到2的原因,不管对数据的屏幕显示有什么影响,唯一行数的明显减少。量化宽松

验证这是否是问题的原因应该很简单,只需观察.Post前后行的键字段值。如果是原因,只需在执行粘贴之前记录要粘贴到的行的键域值,然后在执行.Post之前执行并还原它即可

这个解释让我感到困扰的是,数据集似乎没有抱怨PK密钥违反。可能的原因可能包括数据集在相关列上没有PK/Unique约束,或者网格用作行唯一列的内容实际上不是数据集的PK列

如果上述情况不允许您找到并解决问题的原因,那么在我看来,除非您运气好,并且您的q被有您的问题并知道如何解决问题的cxGrid用户看到,否则您不可能在这里得到完整的答案

没有人能从远处告诉您,除非他们自己遇到过),这是由配置问题(主要是,是否所有网格的属性都设置正确?)还是cxGrid代码中的怪癖引起的。坦率地说,最不可能的原因是网格代码中的错误,因为Devex网格借助其庞大的用户群进行浸泡测试,并且Devex知道他们在编写代码

cxGrid是一个非常复杂的组件,IIRCC绕过Delphi的常用机制(我指的是使用TDataSources等)将数据从相关数据集获取到网格节点,您的问题受到“我们看不到您的屏幕”综合症的严重影响。因此,我认为你必须亲自调查这一点,如果你找不到解决方案或令人满意的解决办法,你最好的办法可能是看看你是否可以把它归结为Devex可以复制并帮助你的东西

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

您的问题可能是由cxGrid在粘贴操作过程中遇到的“状态错误”引起的。这就是为什么,在我之前的一个评论中,我建议移动数据集的光标-网格的代码应该注意到这一变化,并通过与数据集重新同步来强制网格刷新自己,希望这样可以更正行数和网格显示的内容。我建议的方法(下一步+上一步)或两个MoveBy()没有关闭和重新打开数据集的开销。实际上,根据cxGrid的编码方式,只需立即执行DisableControls,然后执行EnableControls,就足以强制刷新。但是,如果我所建议的问题是由将键字段值从一行粘贴到另一行引起的解释是正确的,那么我不希望使用任何这些方法来强制网格更新工作,而只是关闭和重新打开数据集

如果以上都没有找到原因,那么接下来我会从另一端开始调查问题。在Devex源代码中找到.DataController.RowCount的实现,在其内部放置一个断点,并在其返回值上放置一个手表,然后