How do I move multiple nodes at once in a TJvTreeView? - delphi

When you select multiple nodes of a JvTreeView, and then try to drag these nodes, the JvTreeView selects the node you clicked to drag, rather than initiating dragging all the selected nodes. You end up dragging only this single node.
Is it possible to drag multiple nodes in a JvTreeView? I am using Delphi 2007.
UPDATE: Oddly enough, if I hold down CTRL+SHIFT when dragging the items, I can successfully drag them all. Any ideas?

Suppose MultiSelectStyle is the default [msControlSelect], then the answer to your question is 'you don't release the control key when you're selecting the last item and beginning dragging'.
The culprit is in TJvTreeView.WMLButtonDown in JvComCtrls.pas. Code there tests if 'Ctrl' is pressed when the TreeView is MultiSelect, and clears all items and selects the clicked item if 'Ctrl' is not pressed. It should instead test if the clicked item is already selected and do nothing if it is.
You can see the broken behavior without dragging. Multi select a few items and then click a selected item with the mouse. The VCL TreeView do not select or de-select anything, while the JVTreeView, instead, de-selects all items and selects the clicked one.

Yes absolutely, I do it all the time.
Of course Multi-Select needs to be True and you may need to have a look at the TTreeView's MultiSelectStyle. That controls what type of nodes can be selected at the same time. For example if msSiblingOnly is set to true, you can only select sibblings.
Are you using dmAutomatic or dmManual. If the latter, it could be that you are doing something in the OnMouse* events that is negating the multi-selection you made earlier.

Related

What event to call when ListView selected item changed?

I'd like to run a procedure--once--whenever the selected item in a ListView changes. The obvious choice would be OnSelectItem, but it's called twice when the user moves from one selected item to another (using mouse or arrow keys). Similarly, OnChange is called three times when moving between items.
Is there an event generated only once under these conditions? OnClick is generated once, but doesn't cover moving between items using arrow keys, etc.
You can do it like this using OnSelectItem.
Remember the last selected item.
When the OnSelectItem fires, check if the current selected item differs from the one you remembered.
If so, perform your task, and make a note of the new selected item.

How to SelectAll only visible VirtualTreeView items?

I have hidden some VirtualTreeView items using VirtualTree.IsVisible[n] := false;.
In one function I iterate through all selected items using VirtualTree.GetNextSelected(n); method. But there is a problem - if I manually select a few items for example using CTRL-click or SHIFT, the items which get looped are the ones selected.
But if I press CTRL + A to select all then GetNextSelected gives me all nodes, including those which are hidden.
I did a workaround by checking if (VirtualTree.IsVisible[n]) ... to avoid looping through all items and fetch only visible ones, but this seems like a bug or maybe there is an option which controls how CTRL + A will behave - will it select only visible nodes or all of them?
So is this a bug or maybe I missed some selection option (I examined them all) or am I supposed to use some other method for looping only through visible nodes?
As it appears by David Heffernan and Joachim Marder, it is a design choice and not a bug. For this reason, one needs to introduce a workaround when looping through items using GetNextSelected by checking if (VirtualTree.IsVisible[n]) ... to loop only through visible items.

I need a DBGrid OnAfterCellClick

I have three DBGrids and three Tables, and two of them are linked with Master Fields and work as expected. When the user clicks on grid-1, it shows three items in grid-2.
When the user clicks on grid-2, I want to use Locate to select the Row in grid-3
Problem is that the grid-2 OnCellClick event is fired before the data has changed to the appropriate Row. e.g.
Grid-2
Flowers <-- this has focus and Dirt has focus in grid-3
Weeds
Trees <-- then I click here
Grid-3
Dirt
Water
Gum <-- and using Locate in the grid-2 OnCellClick I
want it to show Gum but grid two is still
internally on Flowers and stays on Dirt
It seems that the grid does not change to the Row until after the OnCellClick event.
I need an AfterCellClick event.
Can someone please shed some light on how to go about that?
Thanks
You shouldn't be using OnCellClick. Use the TDataSet.OnAfterScroll instead. It's called automatically when the record (row) pointer is moved, after the movement is done. This means that when the grid attached to the second table is clicked and the record pointer is moved from Flowers to Trees, the second table's OnAfterScroll event will be fired after the row changes, and in that event handler you can do the appropriate Locate in the third table.

Show different popup menu depending on what column the mouse is over in a Delphi TListView control?

I have a Delphi 6 application that has a TJvListView control. I have a popup menu tied to that control via the control's PopupMenu property. What I would like to do is show a different popup menu based on which column the user had the mouse over when they right clicked, with the additional option to not show a popup menu at all if the current column does not need one. How can I do this?
Thanks to this detailed sample by Remy Lebeau on in-place editing in a TListView I know what row and column the mouse is over except for one wrinkle. The mouse down event where I determine the current row and column occurs after the popup menu is exited.
I now need to know two things. First, how can I get some event to fire before the popup menu shows after a right mouse click so I can record the current list view row and column and suppress the popup menu if I want to, and second, how I can show a different popup based on the current column. I am hoping to avoid having to write a bunch of mini-forms instead of using the TListView PopupMenu property and supporting code. Is there a simple solution, perhaps some fancy footwork in a sub-class I should create around TJvListView?
You could perform the detection in mousemove instead of mousedown/Click and change the popupmenu depending.
You also could remove any popupmenu and call the wished via p.pupup in mousedown as you desire.

Bring Control to Front when Selected in the Structure Pane

I would like to build a Wizard component, where I can guid the user through different pages. When the last page is reached, an action is performed.
That component should work similar as the TPageControl, where I can create sheets at design-time. Creating that 'sheets' is already done, but my problem is, that the last added sheet is always on top of the other sheets, and I cannot select another one anymore (which are behind). In the TPageControl component, I can select a sheet in the Structure Pane, and it comes to the front, where can I put controls on it.
And this is my question: How can I bring a control (my wizard sheet) to the front, when it is selected in the Structre Pane?
I have to override the TWinControl.ShowControl function. That function is fired when you click in the structure pane on the child control. Then, I just need to invoke the BringToFront function of that child.

Resources