我没有遇到Delphi 10 Seattle下TScrollBar的Event(OnScroll)处理程序的解决方案。我选择它是因为它不是我将把任何内容放入的TScrollBox(如Panel或DBGrid)。它只是检测鼠标动作(MouseUp / Down / Side-to-Side都没有工作),它将被用作文件搜索工具,它将强制一堆TeeCharts更新,基于在滚动的方向。
到目前为止,我只遇到了由WindowsMessages(WM_HScroll)和VLC.StdCtrls.TScrollBar.OnScroll
组成的难以理解的示例。除了OnChange之外,检测ScrollBar移动的有效方法是什么?
能够操纵ScrollBar并将其自身重置在中间是有帮助的。就像我设置的值非常相似,如果我设置Min = -50和Max = 50(0)
答案 0 :(得分:0)
要克服FMX TScrollBar
的限制,您可以使用以下内容作为进一步增强的基础(部分受您提供的链接启发)。
如果您将使用滚动条滚动的控件具有(或可以配备)存储当前滚动位置的属性,您可以使用/定义类型single
。对于测试,我只是将其定义为表单的私有属性,并将其命名为sbIncremental
。
我将TScrollBar
的属性设置为Orientation = Vertical
,SmallChange = 10
,Max = 100
和Min = -100
然后,OnChange
事件在我的测试中看起来像这样:
procedure TForm6.ScrollBarChange(Sender: TObject);
var
sb: TScrollBar;
sbOnChange: TNotifyEvent;
begin
sb := (Sender as TScrollBar);
sbIncremental := sbIncremental + sb.Value;
Label1.Text := FloatToStr(sbIncremental); // Use the new value
sbOnChange := sb.OnChange; // Disable OnChange event
sb.OnChange := nil; // -"-
sb.Value := (sb.Min + sb.Max) / 2; // Reset position
sb.OnChange := sbOnChange; // Re-enable OnChange event
end;
要将ScrollBar位置重置为中心,我们需要暂时禁用OnChange事件。
评论后更新。
正如我现在所理解的那样,你的问题是滚动条的视觉外观不会返回到零位置,即使它的值被改变(在OnChange内)为零(min = -100且max = 100为零)位置在中间)。单击箭头按钮时会发生这种情况,但如果拖动拇指按钮或单击拇指按钮的任一侧则不会。在OnChange事件中的这两种情况下似乎可以防止可视更新。此外,调用ScrollBar.Repaint不会更新视觉外观。我发现无法使用OnMouseDown / OnMouseUp事件。它们似乎没有内部联系?
这给我们留下了以下(hacky)解决方案:使用一个小延迟,比如300毫秒来启动计时器。发生超时时,滚动条已准备好接受新值更改并直观更新。计时器也有正面效果,拇指握柄在你点击时移动,然后向后移动。没有任何时间之间就没有可见的迹象表明事情发生了。
使用计时器时的OnChange事件处理程序
procedure TForm6.ScrollBarChange(Sender: TObject);
begin
// Use the scrollbar value
Label1.Text := FloatToStr((Sender as TScrollBar).Value);
// Enable reset timer
ScrollBarTimer.Enabled := False;
ScrollBarTimer.Enabled := True;
end;
OnTimer事件
procedure TForm6.ScrollBarTimerTimer(Sender: TObject);
var
sbOnChange: TNotifyEvent;
begin
ScrollBarTimer.Enabled := False;
sbOnChange := ScrollBar.OnChange; // store OnChange event
ScrollBar.OnChange := nil; // disable OnChange event
ScrollBar.Value := (ScrollBar.Min + ScrollBar.Max) / 2; // reset position
ScrollBar.OnChange := sbOnChange; // re-enable OnChange event
end;