gpt4 book ai didi

delphi - TListbox 的 OnClick 事件,使用箭头键更改所选项目时调用

转载 作者:行者123 更新时间:2023-12-02 01:54:35 25 4
gpt4 key购买 nike

我的发件人上有一个列表框,其中包含多个项目。当用户单击某个项目(OnClick 事件)时,用户状态会发生更改,并且 TCP 服务器会收到通知。如果我使用键盘上的箭头键,则会调用相同的事件,如 OnChange 事件。但是没有 OnChange 事件。

使用箭头键的问题是,如果用户快速移动多个项目,我的通知服务器方法会被调用多次。 (这样不好)

为了解决这个问题,我在 OnKeyPress 事件上放置了一个计时器。当按下箭头键时 如果用户停止按下箭头键 2 秒,则调用通知服务器方法,通知服务器一次。 (理论上)

OnKeyPress 和 OnClick 仍然被调用。

有没有人对 TListbox 足够熟悉,可以向我解释为什么会发生这种情况,以及是否有更好的方法来思考这个问题?用户要求是使用列表框,并且不禁用箭头键。

最佳答案

当用户单击 ListBox 时,会触发 OnClick 事件,但当选择因任何原因实际发生更改时,也会触发该事件。这是 TListBox 实现方式中的一个设计缺陷(恕我直言)。它应该像其他组件一样公开实际的 OnChangingOnChange 事件(因为底层 ListBox 控件提供此类通知)。

但是,您可以使用以下方法来区分鼠标单击和键盘箭头按键:

如果按住向上/向下箭头,则在 OnKeyDown 事件中设置一个标志。

清除 OnKeyUp 事件中同一箭头键的标志。

然后,您可以在 OnClick 事件中检查该标志(或者更好的是,子类化 ListBox 以直接拦截 LBN_SELCHANGING/LBN_SELCHANGE 通知)。如果设置了该标志,则启动计时器以延迟服务器操作,否则立即执行您的操作。

例如:

type
TForm1 = class(TForm)
...
private
IsArrowDown: Boolean;
...
end;

...

procedure TForm1.ListBox1Click(Sender: TObject);
begin
if IsArrowDown then
begin
Timer1.Enabled := False;
Timer1.Interval := 1000;
Timer1.Enabled := True;
end else
UpdateUserStatus;
end;

procedure TForm1.ListBox1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key in [VK_DOWN, VK_UP] then
IsArrowDown := True;
end;

procedure TForm1.ListBox1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key in [VK_DOWN, VK_UP] then
IsArrowDown := False;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
UpdateUserStatus;
end;

procedure TForm1.UpdateUserStatus;
begin
// notify server as needed...
end;

更新:双击还会OnDblClick 事件之前触发OnClick 事件。因此,如果您需要区分单击和双击,则还必须使用计时器:

type
TForm1 = class(TForm)
...
private
IsArrowDown: Boolean;
...
end;

...

procedure TForm1.ListBox1Click(Sender: TObject);
begin
if IsArrowDown then
begin
Timer1.Enabled := False;
Timer1.Interval := 1000;
Timer1.Enabled := True;
end else
begin
Timer1.Enabled := False;
Timer1.Interval := GetDoubleClickTime() + 500;
Timer1.Enabled := True;
end;
end;

procedure TForm1.ListBox1DblClick(Sender: TObject);
begin
Timer1.Enabled := False;
UpdateUserStatus;
end;

procedure TForm1.ListBox1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key in [VK_DOWN, VK_UP] then
IsArrowDown := True;
end;

procedure TForm1.ListBox1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key in [VK_DOWN, VK_UP] then
IsArrowDown := False;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
UpdateUserStatus;
end;

procedure TForm1.UpdateUserStatus;
begin
// notify server as needed...
end;

关于delphi - TListbox 的 OnClick 事件,使用箭头键更改所选项目时调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30787156/

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