Notifications
Clear all

[Closed] Replacement for Vertical Scroll

I’m looking to find more elegant solution which will replace ugly vertical scroll when user decide to manually change size (height) of .net form.It’s not important to change visibility when form have maximal height ei. scroll is always visible. In next examle blue stripe on the right side represent place and width of the scroll.

if testForm != undefined do try(testForm.Close())catch()	
 (	
 	fn maxHW = (dotNetObject "maxCustomControls.win32HandleWrapper" (dotNetObject "System.IntPtr" (windows.getMaxHWND())))
 	fn defColor r g b = ((dotNetClass "System.Drawing.Color").FromArgb r g b)
 	fn defSize w h = (dotNetObject "System.Drawing.Size" w h)
 	fn defRect x y w h = (dotNetObject "System.Drawing.Rectangle" x y w h)
 	local maxBC = (clr = (colorMan.getColor #background) * 255.0 ; defColor clr.x clr.y clr.z)
 	local maxFC = (clr = (colorMan.getColor #Text) * 255.0 ; defColor clr.x clr.y clr.z)
 	local scrollClr = defColor 51 175 235
 	fn defForm dnFrm w: h: bg:maxBC = 
 	(
 		dnFrm.FormBorderStyle = dnFrm.FormBorderStyle.SizableToolWindow
 		dnFrm.ClientSize = (defSize w h) ; dnFrm.Text = "test form" ; dnFrm.BackColor = bg
 		dnFrm.StartPosition = dnFrm.StartPosition.CenterScreen ; dnFrm.ShowInTaskbar = false
 		dnFrm.Icon = (dotNetClass "ManagedServices.AppSDK").GetMainApplicationIcon()
 		dnFrm.MaximumSize = defSize w 500 ; dnFrm.MinimumSize = defSize w 105
 	)
 	fn defFPnl fPnl w: h: clr:maxBC =
 	(
 		fPnl.Size = defSize w h ; fPnl.BackColor = clr
 		fPnl.AutoSizeMode = fPnl.AutoSizeMode.GrowAndShrink
 		fPnl.WrapContents = fPnl.AutoSize = on
 		fPnl.FlowDirection = fPnl.FlowDirection.TopDown
 	)
 	fn defLbl rollLbl w: h: txt: bg:maxFC fg:maxBC =
 	(
 		if txt == unsupplied then rollLbl.Bounds = defRect 149 5 w h else (rollLbl.Text = txt ; rollLbl.margin = (dotNetObject "padding" 1 2 1 2))
 		rollLbl.Size = defSize w h ; rollLbl.BackColor = bg ; rollLbl.ForeColor = fg
 		rollLbl.TextAlign = rollLbl.TextAlign.MiddleLeft
 		
 	)
 	testForm = dotnetObject "Form" ; defForm testForm w:170 h:500
 	floatPnl = dotNetObject "FlowLayoutPanel" ; defFPnl floatPnl w:150 h:300
 	-- *vScroll* label shows place and size (width only) of vertical scroll 
 	vScroll = dotNetObject "Label" ; defLbl vScroll w:3 h:300 bg:scrollClr
 	floatPnl.Controls.addRange (for i = 1 to 15 collect (lblCtrl = dotnetObject "Label" ; defLbl lblCtrl w:145 h:18 txt:("Control_"+i as string);lblCtrl))
 	testForm.Controls.AddRange #(floatPnl, vScroll)
 		
 	testForm.Show(maxHW())		
 )

Thanks in advance.

68 Replies

you want to make you own custom scrollbar, don’t you?
but another thing that you have to do is to support with this scrollbar full functionality of scrollable control… there are many rules actuality that make its functionally habitual to a user:

move on drag

be the size proportionally to number of items(scroll area)

support small and large increment

support setting the value by clicking the bar (not cursor)

and many other…

so the makings a look of the custom scrollbar is only 10% of its codding. doing the full coding you would ask yourself which scrollbar control is really ugly.

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

I know that “background” code of original v-Scroll is very complex like the spinners of NumericUpDown control. What I especially dislike is default system color (sylver white) and width. If I not change width of form then vScroll will overlap all controls. I prefere darker GUI look also.
The rules that should have custom vScroll in my case

only the bar (not spinners at the top an bottom)

move on drag and alway visible (like shown blue stripe)

the size proportionally to number of items ei. height of container (Panel or FlowLayoutPanel)

All controlls (buttons, spinns, labels etc.) will be placed inside resizable FlowLayoutPanel.
Maybe is the best to use Label object for this, but how to create “the rails” on which will be moved :hmm:

some of built-in scrollable controls have a scroll property, so they can be programmatically set. you have to update your custom scroll bar in this case.
what do i want say? it might be easier to change a look of built-in scrollbal control than implement your own from scratch.

with your love to ‘custom looking’ controls you should stick with WPF long ago.

look at this sample http://www.codeproject.com/Articles/37366/Styling-A-ScrollViewer-Scrollbar-In-WPF

I know. But now is late.
I already created custom look of my tool with mxs+.net and I stuck with this problem. I only need simplified version of vScroll.
Also there is no need for control. Can we paint rectangle (blue stripe) to indicate location of vScroll area on empty space of form.
When user place the cursor here cursor will change icon to up-down arrow.
Now using “mouse down”, “mouse move” and “mouse Up” events this can be done, I guess?
And only rule for that will be #move on drag.

Wow. The example is very cool. But code is too long. I already have many controls and knowing that WPF have some limitations I will stay away from it for now
But for the next less complex tool I will consider this for sure.
Thanks.
Now what do you think about my previous approach. Is it hard to do it?

in programming it calls ‘decoration’. you don’t solve the task, you just do it to look like solved.
if you really want to make anything useful for your custom UI solutions you have to implement your own scrollable control with your own scrollbar…
the simplest solution as i see is panel with two children: scrollable panel and … user control for example.

something like:


 try(form.close()) catch() 
 (
 	global form = dotnetobject "MaxCustomControls.Maxform"
 	form.Text = "Show Test"
 	form.ShowInTaskbar = off
 	form.BackColor = form.BackColor.DarkGray
 	form.DockPadding.All = 2
 
 	form.StartPosition = form.StartPosition.Manual
 	form.Size = dotnetobject "System.Drawing.Size" 200 300
 	form.Location = dotnetobject "System.Drawing.Point" 800 200
 
 	p = dotnetobject "UserControl"
 	p.Backcolor = p.Backcolor.Gray 
 	p.Dock = p.Dock.Fill
 
 	sb = dotnetobject "UserControl"
 	sb.Backcolor = sb.Backcolor.Blue
 	sb.width = 8
 	sb.Dock = sb.Dock.Right
 	
 	global tt = dotnetobject "Button"
 	tt.Backcolor = tt.Backcolor.Yellow
 	tt.FlatStyle = tt.FlatStyle.Flat
 	tt.width = 8
 	sb.controls.add tt
 	
 	global fp = dotnetobject "FlowLayoutPanel"
 	fp.dock = fp.dock.fill
 	fp.backColor = fp.backColor.Orange
 	fp.FlowDirection = fp.FlowDirection.TopDown
 	fp.WrapContents = off
 	
 	for k=1 to 20 do
 	(
 		bt = dotnetobject "Button"
 		bt.text = k as string
 		bt.Size = dotnetobject "System.Drawing.Size" 160 24
 		fp.controls.add bt
 	)
 
 	p.controls.addrange #(fp, sb)
 		
 	form.controls.add p
 	form.ShowModeless()
 )
 fp.VerticalScroll.Value = 50 
 
 fn onSizeChanged s e =
 (
 	s.tag.controls.item[0].Height = s.tag.height*(s.Height as float/s.PreferredSize.Height) 
 )
 dotnet.addEventHandler fp "SizeChanged" onSizeChanged
 fp.tag = tt.parent
 onSizeChanged fp undefined
 
1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

From designer point of view this color styles mean “put sunglasses to save your eyes”
Just change please:

tt.Backcolor = tt.Backcolor.dimgray
 sb.Backcolor = sb.Backcolor.black
 fp.backColor = fp.backColor.gray

Joking aside, the concept is good. I like it.
Is it posible to move “tt” button up an down and control scrolling?

hmmm… i’ve thought it’s exactly what a custom controls are for…

well… of course it’s possible to bind ‘thumb’ location and scroll value.
for a FlowLayoutPanel it’s VerticalScroll.Value
but i don’t remember why but this value is settable but not readable. so it might be better to use another scrollable control instead of FlowLayoutPanel.

1 Reply
(@gazybara)
Joined: 11 months ago

Posts: 0

Custom controls can be look nicer then default one.
I like to use FlowLayoutPanel because of FlowDirection prop. Also I don’t think about controls alignement and location.

it’s because you don’t know about ContainerControl

You’re the expert for programming languages. I still learn. I will explore this control.

Page 1 / 5