在Delphi XE7中,我根据是否选择了ListView中的项目,使用此技巧自动启用或禁用工具栏按钮("编辑ListView项目"),以防止用户点击如果没有选择ListView项,则在按钮上:
actTest
。 actTest
分配给按钮。 在OnUpdate
操作的actTest
事件中写道:
procedure TForm1.actTestUpdate(Sender: TObject);
begin
actTest.Enabled := ListView1.SelCount > 0;
CodeSite.Send('actTestUpdate'); // gets fired very often!
end;
现在您可以看到按钮是根据是否选择了ListView中的项目而启用或禁用,与您是使用鼠标还是使用键盘或以编程方式选择/取消选择项目无关。
但是,在CodeSite Live Viewer中,我可以看到actTestUpdate
事件被连续且非常频繁地触发,因此语句actTest.Enabled := ListView1.SelCount > 0;
将被执行。
所以我的问题是:这会降低性能吗?如果是,还有另一种技巧可以实现上述目的吗?
答案 0 :(得分:7)
如果您有(或计划拥有)许多操作,您可能需要将Application.ActionUpdateDelay设置为例如50毫秒。这可以提高性能。
另外,如果你有很多动作,我建议你尝试使用TForm.UpdateActions而不是为每个动作定义TAction.OnUpdate。它将使代码更具可读性。
答案 1 :(得分:4)
是的,OnUpdate
事件处理程序需要时间,就像任何其他例程一样。多个处理程序需要多倍的时间。所有代码的总和将评估导致无关的条件。从这个意义上讲,您可以得出结论,此更新机制会降低性能。特别是考虑到这些更新事件经常发生:
在应用程序空闲或操作列表更新时发生。
这可能是免于使用的原因。但你应该意识到单个表达式的评估大多不需要花费那么多时间。此外,要意识到无论动作更新如何,您的应用程序都会在每次鼠标移动时执行(更加繁重)计算和操作。
当您将代码持续时间保持在最新状态时,将事件更新为最小值,例如没有通过数据库连接进行密码检查,然后性能将正常显示。如果您有与更新操作相关的冗长操作,那么请回到这些特定情况下的手动更新。
请注意,不使用Actions的单个OnUpdate
事件可以略微提高性能,但ActionList的OnUpdate
事件却有Handled
参数取消进一步处理,具有集中化和分类的额外好处。
您的ListView1.SelCount
向控件发送WinAPI消息以检索选择计数。这是一个很小的操作,我不会打扰它所需要的时间。
另一种方法是更新ListView的OnSelectItem
事件中的操作。该事件将捕获由鼠标和键盘交互引起的所有选择更改,以及设置单个项目
Selected
财产:
procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem;
Selected: Boolean);
begin
actTest.Enabled := ListView1.SelCount > 0;
end;
但是,ListView和VCL都没有提供任何信号,只能在SelCount = 0
和SelCount > 0
之间发出信号,因此无论如何,您将更加严格地评估该行代码。
假设MultiSelect
为真,您也可以自行计算选择更改,以免需要调用SelCount
:
private
FListViewSelected: Longbool;
procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem;
Selected: Boolean);
begin
if Selected then
Inc(FListViewSelected)
else
Dec(FListViewSelected);
actTest.Enabled := FListViewSelected;
end;
或者测试所选项目为nil:
procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem;
Selected: Boolean);
begin
actTest.Enabled := ListView1.Selected <> nil;
end;
但话又说回来,没有理由不使用OnUpdate
事件:
procedure TForm1.ActionList1Update(Action: TBasicAction; var Handled: Boolean);
begin
actTest.Enabled := ListView1.Selected <> nil;
Handled := True;
end;
答案 2 :(得分:0)
Action(更新)事件(主要)在Application.Idle中执行。只要您不在事件处理程序中执行时间关键的事情,就不会出现明显的性能下降。