Sunday 15 March 2015

Winforms (Horizontal) Scrollbar Unexplained Behavior -



Winforms (Horizontal) Scrollbar Unexplained Behavior -

when resize form resize handle on bottom right corner of form, fires sizechanged event of user control. within user command have code set maximum , value of horizontal scroll bar.

if resize right, code works expected. when resize left, scrolling thumb gets big , scrolling not work expected. it's if maximum got set low number, debug.writeline shows not case. actually, resize form narrower, toggles between doing right , doing wrong.

i deal scroll bars , when pain. there scrollbar guru knows why happening? googled , searched too, don't know search on.

here code. relevant part called sizechanged event handler, bottom of code.

class="lang-vb prettyprint-override">imports system.reflection public class grid public sub new() ' phone call required designer. initializecomponent() ' add together initialization after initializecomponent() call. setstyle(controlstyles.allpaintinginwmpaint or controlstyles.userpaint or controlstyles.doublebuffer, true) 'or controlstyles.resizeredraw end sub private _firstvisiblerow row private property firstvisiblerow row if _firstvisiblerow nil , rows.any _firstvisiblerow = rows.first end if homecoming _firstvisiblerow end set(value row) _firstvisiblerow = value lastvisiblerow = getlastvisiblerow() end set end property private _headerrow row public property headerrow row if _headerrow nil _headerrow = new row(me, rowheight) each column column in columns _headerrow.cells.add(new cell(column, _headerrow)) next end if homecoming _headerrow end private set(value row) _headerrow = value end set end property private _lastvisiblerow row private property lastvisiblerow row if _lastvisiblerow nil _lastvisiblerow = getlastvisiblerow() end if homecoming _lastvisiblerow end set(value row) _lastvisiblerow = value end set end property private _totalcolumnwidth integer friend property totalcolumnwidth integer if _totalcolumnwidth = nil _totalcolumnwidth = gettotalcolumnwidth() end if homecoming _totalcolumnwidth end set(value integer) _totalcolumnwidth = value setscrollbarvisibility() end set end property private _totalrowheight integer friend property totalrowheight integer if _totalrowheight = nil _totalrowheight = gettotalrowheight() end if homecoming _totalrowheight end set(value integer) _totalrowheight = value setscrollbarvisibility() end set end property private _visiblegridsize size private property visiblegridsize size if _visiblegridsize = nil _visiblegridsize = getvisiblegridsize() end if homecoming _visiblegridsize end set(value size) _visiblegridsize = value visiblerowcount = getvisiblerowcount() setscrollbarvisibility() end set end property private sub setscrollbarvisibility() vscrollbar1.bounds = new rectangle(width - vscrollbar1.width, 0, vscrollbar1.width, height - iif(hscrollbar1.visible, hscrollbar1.height, 0)) hscrollbar1.bounds = new rectangle(0, height - hscrollbar1.height, width - iif(vscrollbar1.visible, vscrollbar1.width, 0), hscrollbar1.height) vscrollbar1.maximum = math.max(0, totalrowheight - height - iif(hscrollbar1.visible, hscrollbar1.height, 0)) hscrollbar1.maximum = math.max(0, totalcolumnwidth - width + iif(vscrollbar1.visible, vscrollbar1.width, 0)) hscrollbar1.value = 0 vscrollbar1.visible = totalrowheight > visiblegridsize.height hscrollbar1.visible = totalcolumnwidth > visiblegridsize.width debug.writeline(string.format("hscrollbar1.minimum {0}, hscrollbar1.maximum {1}, hscrollbar1.value {2}", hscrollbar1.minimum, hscrollbar1.maximum, hscrollbar1.value)) end sub private _visiblerowcount integer private property visiblerowcount integer if _visiblerowcount = 0 _visiblerowcount = getvisiblerowcount() end if homecoming _visiblerowcount end set(value integer) _visiblerowcount = value lastvisiblerow = getlastvisiblerow() pageheight = getpageheight() end set end property private function getlastvisiblerow() row if not rows.any homecoming nil homecoming rows(math.min(firstvisiblerow.index + visiblerowcount - 1, rows.count - 1)) end function private function getpageheight() integer homecoming rowheight * getvisiblerowcount() end function private function getrowheight() integer homecoming textrenderer.measuretext("x", font).height + 6 end function private function getvisiblegridsize() size homecoming new size(width - iif(vscrollbar1.visible, vscrollbar1.width, 0), height - headerrow.height - iif(hscrollbar1.visible, hscrollbar1.height, 0)) 'don't count header row or horiz scroll bar end function private function getvisiblerowcount() integer homecoming math.ceiling(visiblegridsize.height / rowheight) end function public shadows sub refresh() clearselection() _headerrow = nil _rows = nil autosizecolumns() totalrowheight = gettotalrowheight() invalidate() end sub friend function gettotalcolumnwidth() integer homecoming columns.select(function(x) x.width).aggregate(0, function(x, y) x + y) end function friend function gettotalrowheight() integer homecoming rows.select(function(x) x.height).aggregate(0, function(x, y) x + y) end function private function visiblerows() list(of row) homecoming rows.where(function(x) x.index >= firstvisiblerow.index andalso x.index <= lastvisiblerow.index).tolist end function private sub grid_paint(sender object, e system.windows.forms.painteventargs) handles me.paint e.graphics.clear(backcolor) 'e.cliprectangle dim left integer = -hscrollbar1.value each column column in columns left = column.draw(e.graphics, left) next dim top integer = headerrow.draw(e.graphics) each row row in visiblerows() top = row.draw(e.graphics, top) next end sub private sub grid_scroll(sender object, e system.windows.forms.scrolleventargs) handles me.scroll if e.scrollorientation = scrollorientation.verticalscroll select case e.type case scrolleventtype.first firstvisiblerow = rows.first case scrolleventtype.last firstvisiblerow = rows(rows.last.index - visiblerowcount + 1) case scrolleventtype.smalldecrement firstvisiblerow = rows(math.max(firstvisiblerow.index - 1, 0)) case scrolleventtype.smallincrement firstvisiblerow = rows(math.min(firstvisiblerow.index + 1, rows.last.index - visiblerowcount + 1)) case scrolleventtype.largedecrement firstvisiblerow = rows(math.max(firstvisiblerow.index - visiblerowcount, 0)) case scrolleventtype.largeincrement firstvisiblerow = rows(math.min(lastvisiblerow.index, rows.last.index - visiblerowcount + 1)) end select end if invalidate() end sub private sub grid_sizechanged(sender object, e system.eventargs) handles me.sizechanged visiblegridsize = getvisiblegridsize() end sub private sub hscrollbar1_scroll(sender object, e system.windows.forms.scrolleventargs) handles hscrollbar1.scroll invalidate() end sub end class

the autoscroll property of usercontrol getting set true parent control. 1 time set false in designer, code works expected 100% of time.

winforms

No comments:

Post a Comment