Thursday, December 07, 2006

Autosizing Datagrid with Horizontal Scrolling

Today I was tasked with creating a spreadsheet like datagrid, one with more columns than what the available real estate would be able to show. The datagrid was to always use the maximum screen space available so that for those users with huge budgets and subsequently huge monitors would not need to scroll. For all other, more mortal users, the datagrid should simply scroll off to the right, with a nice horizontal scroll bar.

I figured this would be easy. Turns out it's a bit tricky. If I set the maxWidth of my datagrid to something smaller than the sum of my column widths, the desired behaviour would occur. I'd get a nice horizontal scroll bar and the columns would span out to the right. The problem with maxWidth is that it does not accept percentage values. So if I want the datagrid to use up 100% of the width of the parent container, I can't use maxWidth.

I tried sticking the datagrid in a canvas, thinking i'd be able to use the scrolling of the canvas to quasi hover/move over the datagrid rendered in its entirety underneath, but the vertical scrolling didn't really work out well. Perhaps someone else might have more luck with this approach. I kinda wanted to get back to using the scrollbars in the datagrid, as it seemed that this HAD to be possible!

I figured the solution had to lie in maxWidth. I put the datagrid inside a canvas and made the canvas size percentage based. I then, in a resize() function triggered by creationComplete of the app, assigned the value of the width of the canvas to the maxWidth property of my datagrid. This seemed to work. I also tried to have the resize event of the app call this function instead but I'd get null errors. Turned out I needed to assign the event listener on creationComplete.

Everything looked good, the datagrid was resizing with the canvas. At certain times however the datagrid seemed to lag behind and not fill the canvas properly. Using callLater fixed this. Here's the Demo. Right click on the demo to get the source.

3 comments:

Anonymous said...

Thanks! works great, just what I've been struggling with.

Anonymous said...

Thanks heaps Vic. I was building something very similar ... a scheduler which is very spreadsheet like except that it also has pagination.

I created a way of determining the height. My renderer was a list with another VBox renderer inside that so I created a hashmap for each row to determine the overall height which was accurate but the datagrid still wasn't behaving itself. I tried what you suggested and "wrapped" the datagrid in a canvas and bound the height generated from my hashmap calculation to the canvas rather than the datagrid and it worked a treat :)

Basarat said...

Thanks Vic!