What does a StringGrid's OnSetEditText event do? - delphi

I thought OnSetEditText was fired whenever text in a cell changed. After setting a breakpoint and experimenting, I know that's wrong :-) So, first, when is this event fired?
Second, if I would like to have the text inside a grid cell continuously autosized, which event should I be coding to make this happen (note: I am using TMS's string grid derivative which includes a method for autosizing rows; I just have to figure out when to call it)?

The OnSetEditText event is fired every time the user changes the contents of the in-place editor control, assuming, of course, the control is editable (goEditing in Options). This is confirmed by the documentation, the VCL source code, and black-box verification.

Related

Delphi 10 TMS FireMonkey grid - problem with SelectRows() and RowSelectionCount

I am using TMS FireMonkey Grid in my app and currently trying to implement the ability to select a range of rows by double-clicking on the first row and then double-clicking on the last row of the range. I use the SelectRows(StartRow,EndRow) method in the OnCellDblClick event handler. It seems to work, except for one thing: the RowSelectionCount does not get set properly (equals 1, regardless how many rows I select) until I call ShowMessage() with something random, like 'Hi!' - after that it gets set to a correct number of selected rows. I figured it has something to do with focus, so I tried to use the SetFocus to change focus to another component of the form and then back to the grid, but that didn't help. Any ideas on how to get RowSelectionCount to carry a correct value right away?
The grid's SelectionMode property is set to smDisjunctRow - according to an email I received from TMS Support, this setting should allow me to use RowSelectionCount.
Thanks in advance!

Why OnHScrollChange is not fired in stringgrid in Firemonkey?

Why OnHScrollChange is not fired in stringgrid in Firemonkey? How should i catch the scrolling event in Stringgrid?
OnHScrollChange is fired when you scroll with the scrollbar thumbgrip or its buttons. It is however not fired by changing the selection with the left and right arrow keys, even if that would result in the thumbgrip of the scrollbar being moved.
If your question is about the latter situation, I kind of agree with you that it should trigger the OnHScrollChange, but then again, I have no idea of any design decisions. You may want to enter a report at Embarcadero's Quality Portal and see how they respond.
Another possibility is to use the OnViewportPositionChange event instead which fires however the viewport position changes. The caveat is that it fires also on vertical scrolling. If this is ok for you then that is your solution.

Need to Update a file after a DBGrid Double-Click

I seem to have a mental block with this one.
I need to save recent changes to a Record. I am doing it OK with buttons for "New" "Edit" "Post" "Next" etc but when a user double-clicks a DBGrid, it is now too late to make changes as the DBGrid selection has moved the database cursor to the selected record.
I can't use AutoUpdate as the data that may have been changed is not something the user would have directly entered, it is a value that is changing all the time.
I'll try to describe it better: While the user is reading a Test-page, a timer is counting down or up. When they click the "Next" or "Prior" buttons I can save the timer setting. But, if they Double-Click the DBGrid I have no way of first changing the current Record before the selection moves to the clicked-Record.
I tried using the
Procedure TForm1.tblTestOnBeforeScroll(...
begin
tblTest.Edit;
tblTest.FieldByName('TimerCt').AsInteger:=ClockCtr;
tblTest.Post;
end;
But, that crashed the database, not surprisingly, but I thought I would give it a try before asking here.
How do I deal with the current record? I do not want to disallow the double-click if possible as it seems nice and intuitive for the user.
I'm afraid that what you do on DBGrid is a wrong in concept action.
Key point is DBGrid is a data aware control. So everything you do on it must based on it's datasource then it's dataset.
There is a DblClick event on TDBgrid. But still you have to check it's dataset to see what record is active.
The code you shown above clearly lead you to an endless loop.
When you doing a scroll, the dbgrid will call OnBeforeScroll event, moving the active record
and call OnAfterScroll. Your OnBeforeScroll code does an data update. Then dbgrid abort its operation cause of data change. Then after data update, it try to scroll again, and the data change happen again. Endless loop happen here.
best regard
Apologies in advance if I'm misunderstanding you, but it seems to me that either the premise of your question is wrong or there is something relevant you haven't told us about what you're doing. Please try the following:
If you don't have one already, please temporarily add a DBNavigator to your form and connect it to the same DataSource as your DBGrid. The point of doing this is so that you can more clearly see what's going on.
Then, in your DBGrid's Options, set dgEditing to True.
Finally, comment out or disable your BeforeScroll handler, save and run your program.
Now, click once in some cell in your DBGrid that contains a value which it's ok to change. Click it a second time so that it selects the value in the cell rather than the cell per se.
Make some change to the cell value, but do nothing else for the time being. You should notice that a) the current record indicator of the DBGrid has changed from a black triangle to an I-Beam graphic, like ][ and b) that the tick and cross buttons of the DBNavigator are now enabled.
Now, without doing anything else on the form, click in another row of the DBGrid. You should find that a) the change to what was the current record in step 5 has been saved and b) the current row indicator reverts to the black triangle and the DBNav's tick and cross buttons are disabled.
(If you don't get the behaviour I've just described, create a minimal new project and try that instead, as some other change you've made in your existing project may be interfering with it).
What I've described in 5 & 6 is the default behaviour of a DBGrid and insofar as I understand your q, that seems to be the behaviour you're trying to achieve. If that's not the behaviour you want, please explain exactly how what you do want differs. It's not clear to me where the user double-clicking on the grid comes into your q, except that that action may move the dataset's cursor (if the dbl-click is on a different row than the current one), but as the default DBGrid behaviour will save changes to the current row before it moves the dataset's cursor, it will do what you seem to want automatically.
Btw, what "AutoUpdate" do you mean? Did you mean TDataSource's AutoEdit property?

Delphi 6 TListBox OnMeasureItem() and OnDrawItem() never called for lbOwnerDrawVariable() list box

I have a Delphi 6 app with a TListBox control set to lbOwnerDrawVariable. At run-time I add a single string to the list box. I have event handlers for OnMeasureItem() and OnDrawItem() and I set breakpoints on the very first line of code in each event handler. However neither of them are ever called. Not once. Not even if I make an Explicit Refresh or Repaint call on the list box.
This is really basic stuff so what is it that I am doing wrong that could inhibit the calling of those event handlers and subsequently disrupting my owner draw code? The single string does show in the list box properly. I threw in an OnClick() event handler just to see if it worked and did.
The OnMeasureItem and OnDrawItem events are (indirectly) triggered in response to the WM_MEASUREITEM and WM_DRAWITEM messages from Windows. Make sure you do not have any message handlers in your app that are filtering out that message, or the VCL's internal CN_MEASUREITEM and CN_DRAWITEM messages.
It turns out the problem was due to a non-zero value in the Columns property of the TListBox I was using. I had been experimenting with using columns earlier before I converted over to owner-draw and had left the TListBox.Columns property with a non-zero value. Apparently a non-zero Columns property value inhibits the triggering of owner-draw related event triggering. Once I set that property back to zero OnMeasureItem() and OnDrawItem() started firing.
There's really very little that can go wrong here. If you set up a test app to try this out then it functions just as you would expect and the event handlers are called.
The most likely cause of the behaviour you report is if the items are added before the event handlers are assigned. This typically happens if the items are added at design time in the .dfm file. You say you are adding the items at runtime. Perhaps you are adding them too soon, before the event handlers are assigned. What happens if you add items in response to an event, e.g. a button click. Try that out because you can be sure then then the event handlers are assigned by that point.
If that doesn't help then clearly you have some code in your app that is interfering with the VCL code.
I had this same issue: my OnDrawItem event handler was not being called if the Columns property was non-zero. It turned out this was because the Style property was set to lbOwnerDrawVariable. Variable item height is not allowed in conjunction with multiple columns, presumably because the rows would not line up across the columns if the item heights were allowed to be different. Once the Style property was set to lbOwnerDrawFixed the OnDrawItem event handler was called as expected.
I had a similar problem with a csOwnerDrawVariable-style combobox not triggering the OnMeasureItem event. As David Heffernan suggested, the issue was that the items had been added to the list at design time. The work-around I ended up using was to add code to the FormCreate event handler to copy the design-time list to a temporary variable, then clear the list and add the items back. Kludgy but effective.

Cause 'hint' to refire on listview as I move over items

Sure I've seen this done before but off-hand I can't find any examples.
I've got a TListView, set in 'report' viewstyle. It has about half a dozen subitems, and one thing we'd like to do is have the 'hint' (tooltip) on the listview dynamically show another field of data. That is, each time you move the mouse over any given row, the 'hint' would show some text relevant to that particular row.
I'm partway there - I can do this using the OnInfoTip method, but unfortunately once a tip has appeared, Windows seems to decide that I don't need to see a hint for the listview again until I move the mouse away from the listview and then back 'over' it again. Simply moving the mouse down to the next row, all-the-time keeping the mouse over the control, doesn't persuade the program to display the new hint.
Just to be clear - I've got OnInfoTip working so that the program does display the right hint relevant to the item I first moved the mouse over. Changing the hint text isn't the issue. The problem is that moving the mouse to another item in the listview doesn't cause the software to show a new hint. (Hope that makes sense).
Is there some proper way of getting this behaviour to work, or am I going to end up doing something icky with mouseovers and then manually drawing a hintbox (etc)?
check the following link:
Display Custom Hints for TListView Sub Items
Edit:
I just checked it now on delphi7 it's showing the hint for every row dynamically after moving the mouse on the listview.
Offtopic: This is simple in Virtual Treeview component, it is build-in feature.
i was using the OnInfoTip event (i didn't need hints for the subitems). the hint was "flashing" (show/hide/show/hide/show/hide/show/hide). found the listview's ShowHint was false. set it to True and it worked as it should.

Resources