gpt4 book ai didi

delphi - VirtualTreeView:正确处理选择更改

转载 作者:行者123 更新时间:2023-12-03 14:40:04 25 4
gpt4 key购买 nike

对于那些自己没有遇到过这个问题的人来说,这个问题似乎是显而易见的。

我需要处理 VTV 中的选择更改。我有一个简单的节点列表。我需要对所有当前选定的节点进行操作

  1. 用户点击节点;
  2. 用户按住 Shift/Ctrl 键单击节点;
  3. 用户使用箭头键导航列表;
  4. 用户通过拖动鼠标创建选择
  5. 用户通过单击空白区域或按住 Ctrl 键单击唯一选定的节点来删除选择

等等。这是最常见和预期的行为,就像 Windows 资源管理器一样:当您使用鼠标和/或键盘选择文件时,信息面板会显示其属性。我只需要这些。这就是我陷入困境的地方。

我的一些研究如下。

<小时/>

起初我使用OnChange。它似乎工作得很好,但我注意到一些奇怪的闪烁,我发现在最常见的情况下(选择一个节点,用户单击另一个节点)OnChange 被触发两次:

  1. 当旧节点被取消选择时。此时选择是空的。我刷新 GUI 以显示“未选择任何内容”标签来代替所有属性。
  2. 选择新节点时。我再次刷新 GUI 以显示新节点的属性。因此会出现闪烁。

这个问题可以通过谷歌搜索,所以我发现人们使用 OnFocusChange 和 OnFocusChanging 而不是 OnChange。但这种方式只适用于单选。对于多重选择、拖动选择和导航键,这是行不通的。在某些情况下,焦点事件甚至根本不会触发(例如,通过单击空白区域删除选择时)。

我做了一些调试输出研究,以了解这些处理程序如何在不同的场景中被触发。我发现一团乱,没有任何可见的意义或图案。

C   OnChange
FC OnFocusChange
FCg OnFocusChanging
- nil parameter
* non-nil parameter
! valid selection


Nodes User action Handlers fired (in order)
selected
0 Click node FCg-* C*!
1 Click same FCg**
1 Click another C- FCg** C*! FC*
1 Ctlr + Click same FCg** C*!
1 Ctrl + Click another FCg** C*! FC*
1 Shift + Click same FCg** C*!
1 Shift + Click another FCg** C-! FC*
N Click focused selected C-! FCg**
N Click unfocused selected C-! FCg** FC*
N Click unselected C- FCg** C*! FC*
N Ctrl + Click unselected FCg** C*! FC*
N Ctrl + Click focused FCg** C*!
N Shift + Click unselected FCg** C-! FC*
N Shift + Click focused FCg** C-!
1 Arrow FCg** FC* C- C*!
1 Shift + Arrow FCg** FC* C*!
N Arrow FCg** FC* C- C*!
N Shift + Arrow (less) C*! FCg** FC*
N Shift + Arrow (more) FCg** FC* C*!
Any Ctrl/Shift + Drag (more) C*! C-!
0 Click empty -
1/N Click Empty C-!
N Ctrl/Shift + Drag (less) C-!
1 Ctrl/Shift + Drag (less) C-!
0 Arrow FCg** FC* C*!

这很难读。简而言之,它表示根据特定的用户操作,将使用随机参数以随机顺序调用三个处理程序(OnChange、OnFocusChange 和 OnFocusChanging)。当我仍然需要处理事件时,FC 和 FCg 有时永远不会被调用,所以很明显我必须使用 OnChange。

但下一个任务是:在 OnChange 内我不知道是否应该使用此调用或等待下一个调用。有时,选定的节点集是中间且无用的,处理它会导致 GUI 闪烁和/或不需要的繁重计算。

我只需要标有“!”的调用在上表中。但从内部是没有办法区分它们的。例如:如果我处于“C-”(OnChange,Node = nil,SelectedCount = 0),则可能意味着用户删除了选择(然后我需要处理它)或者他们单击了另一个节点(然后我需要等待形成新选择时的下一个 OnChange 调用)。

<小时/>

无论如何,我希望我的研究是不必要的。我希望我遗漏了一些可以使解决方案变得简单明了的东西,并且你们能够为我指出这一点。使用我迄今为止所拥有的解决这个难题会产生一些非常不可靠和复杂的逻辑。

提前致谢!

最佳答案

ChangeDelay 属性设置为适当的大于零的值(以毫秒为单位),例如100。这实现了 Rob Kennedy 在他的回答中建议的一次性计时器。

关于delphi - VirtualTreeView:正确处理选择更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7995559/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com