[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.
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.
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
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.
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.
You’re the expert for programming languages. I still learn. I will explore this control.