【问题标题】:TableView not updating while pasting a row in Delphi XE4 and Devexpress VCL 13.1.2在 Delphi XE4 和 Devexpress VCL 13.1.2 中粘贴行时 TableView 未更新
【发布时间】:2014-06-28 08:53:42
【问题描述】:

以下是我正在处理的代码 sn-p:

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

【问题讨论】:

  • "是 3[...] 仍然是 2]" 令人困惑。什么是 RowCount before 您一开始就执行 select-row-copy,并且复制操作应该添加新行或将复制选择的行中的详细信息复制到选择的行粘贴到(如果有的话)?
  • @MartynA - 我的表格视图中有 3 行。我想将第二行的所有单元格复制到第三行。所以当我选择第二行并复制它时,它会被复制到剪贴板上。现在我选择第三行并在那里执行粘贴。复制命令不会添加任何额外的行,而只是从一行复制并粘贴到另一选定的行。
  • @MartynA - 我已经编辑了我的问题并在其中包含了行数。
  • 奇怪。听起来这可能是 cxGrid 的一个怪癖。我这里没有最新版本 - 作为一种解决方法,您是否尝试过做一些应该导致 TableView 自我刷新的事情,比如将底层数据集向前滚动一行然后再向后滚动?
  • 我的意思是,做一些暂时将数据集光标移出当前行然后再移回的操作,例如 .Next 后跟 .Prior 或 .MoveBy(1) 然后 MoveBy(-1 )。顺便说一句,我并不是建议将其作为最终解决方案,更多地尝试缩小问题范围。

标签: delphi devexpress vcl delphi-xe4


【解决方案1】:

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

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

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

现在,如果在粘贴操作中复制的网格列恰好包含网格用来唯一标识行的数据集列,那么在 .Post 中的 ExecutePaste 之后,网格可能会认为 DataController 的节点包含的唯一值比之前少一个,如果这就是它计算其 RowCount 的方式,这就是它的值从 3 下降到 2 的原因,无论对数据的屏幕显示产生什么影响,唯一的表观数量的减少有的行。量子力学

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

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

如果上述方法不允许您找到并解决原因,那么在我看来,除非您很幸运并且您的 q 被遇到过您的问题并知道如何解决它的 cxGrid 用户看到,否则您'不太可能在 SO 上得到完整的答案。

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

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

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

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

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

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    • 2023-01-07
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    相关资源
    最近更新 更多