ScrollChanged event missing the timing for ongoing scroll?
Posted: 02 Sep 2022, 00:53
We have a custom ScrollViewer (inherited from Noesis::Scrollviewer) that's designed to accelerate over time as the user continues to scroll (allowing them to quickly scroll to the bottom of a long list if they hold down the right joystick of the controller). However, while our implementation was originally functioning as intended, it has recently been behaving oddly, and we were wondering if there might be a recent change to the Noesis::ScrollViewer that might be causing this.
The issue seems to be a matter of missed timing. When the user holds down the joystick, it triggers OnMouseWheelExternal(), which applies a flat change via ScrollToVerticalOffset(). This change then sets off the ScrollChanged() event, which is where we apply our custom logic, adding an additional push via another call to ScrollToVerticalOffset() (we have a check to make sure that this doesn't trigger itself again). However, it seems that, before this new vertical value is applied, OnMouseWheelExternal() is called again, and performs its operation upon the OLD vertical offset value instead of the new value that we should have after the ScrollChanged() event. Because of this, the only time that the accelerated scrolling is applied is when the joystick is released, as there finally isn't an OnMouseWheelExternal() call to overwrite our adjusted scrolling. Is this sort of timing an expected result?
This is the code for the OnMouseWheelExternal() call:
Our response to the ScollChanged() event is a bit more complicated, but this is the gist of it:
The issue seems to be a matter of missed timing. When the user holds down the joystick, it triggers OnMouseWheelExternal(), which applies a flat change via ScrollToVerticalOffset(). This change then sets off the ScrollChanged() event, which is where we apply our custom logic, adding an additional push via another call to ScrollToVerticalOffset() (we have a check to make sure that this doesn't trigger itself again). However, it seems that, before this new vertical value is applied, OnMouseWheelExternal() is called again, and performs its operation upon the OLD vertical offset value instead of the new value that we should have after the ScrollChanged() event. Because of this, the only time that the accelerated scrolling is applied is when the joystick is released, as there finally isn't an OnMouseWheelExternal() call to overwrite our adjusted scrolling. Is this sort of timing an expected result?
This is the code for the OnMouseWheelExternal() call:
Code: Select all
void AcceleratedScrollViewer::OnMouseWheelExternal(float wheelRotation, Noesis::Orientation orientation)
{
if (orientation == Noesis::Orientation::Orientation_Vertical)
{
ScrollToVerticalOffset(GetVerticalOffset() - wheelRotation / 3.0f);
}
if (orientation == Noesis::Orientation::Orientation_Horizontal)
{
ScrollToHorizontalOffset(GetHorizontalOffset() - wheelRotation / 3.0f);
}
}Code: Select all
this->ScrollChanged() += [this](BaseComponent* /* sender */, const ScrollChangedEventArgs& args) {
/* calculations and other works happen */
ScrollToVerticalOffset(GetVerticalOffset() + scrollIncrement);
};