I need a string grid which can scroll smoothly, as opposed to locking in the top row / left col positions. When you scroll a TStringGrid, the left visible column and top visible row snap into position along the top/left edges. I need the ability for the user to scroll smoothly, not locking these edges into place.
I wouldn't think this is possible to modify in the VCL TStringGrid (or TCustomGrid for that matter) because it relies on properties such as TopRow, LeftCol, VisibleRowCount, etc.. I'm pretty sure I'll need a third party control, but I'd love to use the TStringGrid if possible, because I already have a lot of code wrapped around it. If I do need a third-party grid, then I'm hoping it works closely enough like the TStringGrid.
The short answer is no, you can´t pixel scroll a TStringGrid. You can simulate a grid using a TScrollBox. You can put a grid inside the TScrollBox, make the grid large enough to fit all rows and cols, and turn off its scroll bars, but some things like keyboard navigation will not work.
Other alternative is to use the TVirtualTree in grid mode or TListView. Both have this pixel scroll you want.
I was looking for something similar. Unfortunately, you can't do it with Borland's code but Lazarus can do it
Scrolling the TStringGrid pixel by pixel
You may want to take a look in their code.
Related
Is there a way to add more than 2 components in HorizontalSplit panel without nesting it?
Splitter position should be based on the space allocated for the component. There is nesting of horizontal split panel but the splitter position is not set based on the component visible space
If you want a separate resizable split area for each of those components, then no, you cannot do that with just one split panel and nesting is indeed the solution. If you are fine with just one split, then you can add a layout instead of a component and just keep inserting more components to the layout.
You can use splitPanel.setSplitPosition for adjusting the split position. If your desired split position isn't static and your contents don't have fixed sizes, you could possibly use a tool like SizeReporter add-on for querying the content sizes. Note that this will undeniably cause some flickering, because you need to add the component to the layout before you can measure its size.
A horizontal splitpanel allows one component on the left and one on the right side.
Nothing more
What do you want to achieve?
If you add two layouts to HorizontalSplit there is nothing stopping you in adding more than one component to those layouts. You can also add new SplitLayouts to existing splitlayouts if you want that.
I am using Delphi 2009 and I have set (of variable length) of records with the data <image, label, file path> and I would like to present those records in gallery-like structurei with the horizontal scroll of the entire list and, possibly, with no vertical scroll.
TDBCtrlGrid seems to be exact solution (I can keep records in the TClientDataSet and there is lot of automation in place), but is vertical-only collection (at least for Delphi 2009), it has Orientation property but (at least in design time) it controls the scrollbar only (places it in the bottom). So - maybe it is still possible to adapt TDBCtrlGrid for horizontal use?
TScrollBox (with TFrame child elements) is another promising solution, but so far I can achieve that all the frames are stacked vertically and I don't see how can I ask them to be side-be-side horizontally. So - is there way to use TScrollBox for horizonatl, gallery like structure?
I have reserved the option to use TcxDBVerticalGrid, but I am doing everything to avoid it - I am not sure about the capabilities of the complex grid to present images with its own image internal component, I prefer to use TImage or TDBImage component (seems to be robust) inside some container of controles (e.g. on TFrame and put those frames in TScrollBox).
Assuming the question is something like "How can I make TDBCtrlGrid work in horizontal mode?"
In addition to setting the orientation, you should also set RowCount and ColCount to some decent values.
The TDrawGrid component has a standard way of determining how much to scroll when you scroll to the right and left for example. I want the same behaviour as with a TScrollBox. The amount scrolled to the right and left is a lot less and you can control that. I was using a TScrollBox for this exact reason until I figured out that I can't have fixed Rows and Fixed Cols anymore because my ScrollBox determines the scrolling.
Is there a short way to do this without creating my own component?
I see lots of DB scroll bar questions, but never seem to find a definitive answer to this one.
There is no option (property) to add/hide DB grid scroll bars, either singly or jointly. The simply auto-appear when needed.
If I don't have enough rows to scroll, I would like my columns to fill the entire grid.
If I design it so then when a vertical scroll bar is added at run-time a horizontal scrollbar is auto-added too (since I just covered the right part of the right most column with a vertical scroll bar, we now need a horizontal scroll bar to see what I am covering).
One option is to design my grid such that there is enough space at the right hand size (how many pixels?) to accommodate a vertical scroll, but that is unsightly until there are enough rows to trigger a scroll bar (if ever).
It seems to me that the most aesthetically pleasing way would be start with a grid which is filled with columns at X pixels wide and increase its width to X + width of vertical scroll bar (or decrease the width of one/some of the grids columns by a total of width of vertical scroll bar) pixels when adding a new row causes the vertical scrollbar to appear.
Am I missing something? Is there a “correct” way to do this, or an industry standard way (I am not asking for a “best” way or anything too subjective, so please don’t close. I believe that a lot of people need to know this).
Is there anything in the standard TDBgrid to facilitate this?
Bonus: I subscribe to TMS components, so if there is a way to do this simply with TAdvDbgrid, that would be fine for me, but a general solution with TDBgrid would be fine.
Non-subjective question: Given that
- I do not want to increase the width of my TDBgrid
- and that I do not want a blank white column at the right when no vertical scroll bar is present
- and that I am willing to decrease the width of my right-most column in order to avoid a horizontal scroll bar appearing when a vertical scroll bar appears
... how do I do so?
[Update]
Ken was rightly awarded the answer becuse his solution is best for most users.
For those like me who already paid for a TMS subscription, I just noticed that their TDbAdvgrid component has a ScrollBars property and when I set it to ssVertical, it does what I want.
Now, if I could only figure out a good way to have fixed header row when it is the only row ...
TJvDBGrid (part of the JEDI JVCL) has this capability built in, and includes source code. It should be able to either do what you need, or give you the details needed to implement your own descendant.
Delphi 2007.
I have a TGrid with more rows than will fit on the screen, and the height of the grid is such that there is a partially drawn row at the bottom.
When I click on this partial row, it jumps up to be fully visible (via a procedure called 'ClampInView' in Grids.pas). But it doesn't stop. Since the mouse is now over a new partially drawn row, that jumps up too.
The net effect is that clicking on the partially drawn row starts selecting cells in a vertical column, spinning all the way to the bottom (or until you release the mouse).
I have replicated this on a fresh winforms project with just a single grid with 100 rows, and no code, so I'm pretty sure it's not something I'm doing in code wrong.
It is bad for me because the form I have in real code has drag and drop type behaviour, so clicking and releasing ~0.1 seconds later on the partial row will pick up the item in the cell and drop it about 50 rows lower. This is definitely not what you expect to happen when you click on a cell.
Any suggestions how to fix/work around this?
This is what I have always done because I think it is tacky to have partially visible rows. I adjust the size of the grid so its client area is an even multiple of row height. You can do that at design time, or it is easy to do via code as well. The kicker would be if you have re-sizable rows. If that is the case then just put the code to resize the grid in the event handler for the row resize event (I believe it has one).
Not only does this prevent the behavior you are trying to fix, but it also (in my opinion) makes your UI look a lot cleaner!
You can try override MouseDown in your grid and do not call inherited MouseDown, if user clicks in "bad" places.