I am trying to implement something similar to Excel's "infinite" scrollability; in that a user can scroll to the "bottom" of the document; but then keep scrolling (using either the scrollwheel or the down arrow on the scrollbar), and more, empty rows are generated for them. I have this mostly working (when using the mouse scrollwheel it works perfectly); but I am having troubles with the SmallIncrement functionality - that is; when the user clicks the down arrow on the scrollbar, it should go down by scrollbar.SmallChange, despite being at the bottom of the scrollbar's scrollable range.
Here is my code (in the handler of scrollBar_Scroll):
int difference = e.NewValue - e.OldValue;
if (e.Type == ScrollEventType.SmallIncrement)
{
if (difference != scrollBar.SmallChange)
{
int increase = (scrollBar.SmallChange - difference);
scrollBar.Maximum += increase;
scrollBar.Value += increase;
}
}
Looking at it in the debugger, this sets the values exactly as I would expect. However, something (not sure what) happens after the function ends, causing scrollBar.Value to be set back to its original value, plus one. If I hold down the down-arrow, it works mostly correctly. It still jumps back up a bit once the button is released.
Any idea what could be causing this, and any way of fixing it?
Cheers!
Edit: Here is my scrollwheel code. It's so similar that it's confusing why it's not working. This is in the containing panel's MouseWheel
event handler.
int desiredValue = scrollBar.Value - e.Delta;
scrollBar.MaximumValue = (Math.Max(normalBottom, desiredValue + scrollBar.LargeChange));
scrollBar.Value = Math.Max(0, desiredValue);
normalBottom
is a variable remembering the "finite" ending of the scrollbar - in excel, this would be either the lowest user-entered data, or the height of the screen; so it scrolls normally above this value (without going negative).
What is happening with your scrollbar is the following: when the user interacts with the scrollbar causing the event and your event handler is called the property value have not yet been updated, after you event handler returns the property is set internally by the scrollbar overwriting the value you set and causing the "jump back" effect you mention. How does it remember what value it have to set? Easy: it's in e.NewValue. And that's exactly your solution, to be able to correctly way to alter the final value of this property during the scroll event just write to e.NewValue as follows:
I want to link theese pages that may be relevant to you: http://msdn.microsoft.com/en-us/library/system.windows.forms.scrollbar.maximum.aspx
Note in remarks (This is why even moving the Maximun you still get it advance only 1):
http://msdn.microsoft.com/en-us/library/system.windows.forms.scrollbar.scroll.aspx http://msdn.microsoft.com/en-us/library/system.windows.forms.scrolleventargs.newvalue.aspx (Gets or sets the new Value of the scroll bar. [Emphasis in sets])