1

I am creating a custom control which can display items inside of itself, so if there are items that are offscreen, i want to user to be able to scroll trough them.

But i can't seem to find any properties or flags in UseStyle() in standard Control class. So how do i create a scrollbar for control?

I know that i can create separate instance of VScrollBar class, and draw it as separate control, but it seems for me as inefficient or wrong way of doing so, i would appreciate suggestions for a way of how to solve this. Thanks.

ZecosMAX
  • 216
  • 1
  • 9
  • Derive your control class from ScrollableControl or Panel instead of Control, set the AutoScrollMinSize property to get the scrollbar(s) to appear. [Example](https://stackoverflow.com/questions/4305011/panel-for-drawing-graphics-and-scrolling/4306333#4306333). – Hans Passant May 21 '22 at 22:07
  • 1
    You can inherit `ScrollableControl` if you want to use standard Scrollbars (or derive from an existing `ScrollableControl`, as Panel) or design your own Scrollbars, take some inspiration from [ScrollableControl](https://source.dot.net/#System.Windows.Forms/System/Windows/Forms/ScrollableControl.cs,24feec50034d1f25) and build your own [LayoutEngine](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.layout.layoutengine?) – Jimi May 21 '22 at 22:10
  • You know I'm a big fan of this question and the answer you yourself provided. It seems that you've made a "Scrolling list of custom controls" but the question sounded to me more like "Scrolling over a single large control". I've searched a bunch of times on the _former_ and I wonder if you'd consider reworking the title so that I can upvote the question, too? – IVSoftware May 23 '22 at 12:42
  • @IVSoftware well they are not exactly controls, i don't like the performance issues that a nested control could bring, so i draw everything myself, including icon, selection, colors etc. I just like it more that way – ZecosMAX May 23 '22 at 12:56
  • 1
    @IVSoftware So yes, this is actually a single large control that translates it's content with scrolling – ZecosMAX May 23 '22 at 13:02
  • 1
    Aw shucks! In the past I've had to make "scrolling lists of custom controls" and I've never been happy with what I have to do in order to accomplish that. Always looking for a better way. The solution I use now is called "third-party-libraries" but I remain interested in internals and basics. Thanks for your responses. – IVSoftware May 23 '22 at 13:07

2 Answers2

3

As comments suggested, i've derived my class from ScrollableControl and used AutoScroll property to make scrolling logic into my control.

Sadly Microsoft documentation about ScrollableControl.AutoScrollMinSize lacks details about what this property actually mean. Neither from name nor from description.

It says:

A Size that determines the minimum size of the virtual area through which the user can scroll.

And i couldn't figure out for some time what does this actually mean, only after, i came up with imo better description: A size of a content trough which the user can scroll.

It also says nowhere that for scrollbars to appear this minimal size should be bigger than control itself. And so, i could finally implement what i needed:

Here is the code, that sets AutoScrollMinSize

this.AutoScrollMinSize = new Size(0, _displayedItems.Count * (this.ItemHeight + this.ItemsMargin));
this.VerticalScroll.LargeChange = this.ItemHeight;
this.VerticalScroll.SmallChange = this.ItemHeight / 3;

For X component i have 0, because i don't need horizontal scrolling. For Y component i calculate the size of entire content that user can interact with.

And for actual scrolling of a content, i just translate graphics for scroll value:

e.Graphics.TranslateTransform(0, this.AutoScrollPosition.Y);

And it works just as intended.

scrolling

Hope it help anyone who stumbles on this exact same problem as i did.

ZecosMAX
  • 216
  • 1
  • 9
  • Wow your sample is really nice and I this is one of those times IMO that you should mark your own answer as accepted. I agree about the documentation. I'm upvoting for sure. Do you have this example in a simple runner program? Consider making a public GitHub repo so others could experiment. Truly this is the most useful thing I've seen on the topic. Kudos! – IVSoftware May 23 '22 at 12:28
  • 1
    @IVSoftware well, it's a commercial product, i'm making form for element creation like in VS and Microsoft's listview is just absolutely unusable, so i decided to create my own, i could actually turn this into a separate library with collection of my controls, why not – ZecosMAX May 23 '22 at 12:59
1

If I understand your question, this is what has worked for me to get the scrolling behavior:

If a simple Panel control containing 3 child controls is set to Dock.Fill to the main form with the AutoScroll property set to true it behaves as shown below when the main window is resized to where the content doesn't fit anymore.

As stated in Hans' comment, If the user control inheritance is CustomUserControl : Panel then it will manifest this behavior.

enter image description here

IVSoftware
  • 5,732
  • 2
  • 12
  • 23