The problem with running the context menu of the TreeView object on the form. After the user has left-clicked an item in the tree, he needs to double-click on the right mouse button so that the context menu appears. The customer is very annoyed.

The problem appeared after the treeView on the form was used as a data source in the Drag-Drop drag-and-drop procedure implemented by standard MicroSoft tools.

The following code has been added to the click handler:

 private void treeView_MouseDown(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { TreeNode node = treeView.GetNodeAt(eX, eY); if (node != null) { // ... некоторые предварительные вычисления, // не влияющие на элементы формы, а меняющие Tag у node //Проблемы появились после добавления этой стандартной функции от MicroSoft treeView.DoDragDrop(node, DragDropEffects.Copy); //Это старый код, который должен остаться и при котором все работало treeView.SelectedNode = node; } } } 

Drag-Drop itself is processed without problems.

If it is important, then on treeView_AfterSelect a handler is implemented that fills the form elements with information

 private void treeView_AfterSelect(object sender, TreeViewEventArgs e) { TreeNode currentNode = treeView.SelectedNode; if (currentNode != null) { FillAll(currentNode); } } 

Please tell me how to solve this problem without implementing your own Drag-Drop, or how to explain to the client that this is not a bug in the implementation of DoDragDrop() MicroSoft, but a feature.

A detailed study of this rare phenomenon showed that to stop the procedure of DoDragDrop() not enough just to release the left mouse button. The treeView_MouseUp() handler does not respond to it if the standard DoDragDrop() is used.

UpDate from 12/26/2016: On request, add the code that handles the events of the DragDrop procedure:

1) At the DragEnter event for the ListBox lstBxForSearch; The drag handler is hanged by the following handler:

 private void lstBxForSearch_DragEnter(object sender, DragEventArgs e) { // Предварительно сбрасываем флаг допустимости использования контрола lstBxForSearch, // как приемника процедуры DragDop e.Effect = DragDropEffects.None; // Устанавливаем этот флаг, если объект, который тянем, может быть принят // контролом lstBxForSearch, то есть источником служит контрол treeView if (e.Data.GetDataPresent(typeof(TreeNode))) { TreeNode node = e.Data.GetData(typeof(TreeNode)) as TreeNode; if (node != null && node.TreeView == treeView) { //Допустимый источник e.Effect = DragDropEffects.Copy; } } } 

2) At the DragDrop event for ListBox lstBxForSearch; such handler is hanged:

 private void lstBxForSearch_DragDrop(object sender, DragEventArgs e) { //Анализируем, что принесли на мыше TreeNode node = e.Data.GetData(typeof(TreeNode)) as TreeNode; if (node == null) return; addPlantToSearchList(node); } 

and correspondingly

 private void addPlantToSearchList(TreeNode currentNode) { PlantExtendTag tg = currentNode.Tag as PlantExtendTag; if (tg == null) return; MyDS.PlantShort_ViewRow plantRow = tg.PlantRow; if ((TacsonomyLeve)plantRow.LevelNum == TacsonomyLeve.Kind) { lstBxPlantsForSearch.Items.Add(new NameId(plantRow.Id, currentNode.Text)); } else { toolStripStatusLabel.Text = "Расширенный поиск предусмотрен только по пересечению видов"; } } 
  • could not reproduce the problem. The context menu is normally invoked with one right click, after DragDrop. All events work out. Most likely an error in some fragment that you did not bring in the question. - rdorn
  • The AterSelect event and the filling of the node have nothing to do with it. How do you call up the menu, maybe the problem is there? add this snippet. Well, the DragXXX event handling code doesn't hurt either. - rdorn
  • rdorn, thank you so much for participating in my problem. The fact is that if you move the mouse just a little bit, the problem disappears. It takes place if the mouse remains stationary. Then to call the context menu, you need to double-click on the right button. One gets the feeling that the DoDragDrop () developer has forgotten that the procedure needs to be stopped by _MouseUp (), even when the mouse is stationary. The context menu is simply tied to the tr view, via property. Event code DragXXX now lay out. - Alexander Muksimov
  • Code added. Well and just in case that, there was complete information - the context menu is added by the regular form designer in VisualStudio. - Alexander Muksimov
  • ok, in the absence of mouse movements, I confirm the bug with the right click, and sometimes it takes more than two clicks, obviously the number of clicks depends on the weather on Venus ... - rdorn

1 answer 1

TreeView has a special event TreeView.ItemDrag . This event is triggered when, after we begin to pull the element with the mouse button held down (you can configure which key). With a normal click, it does not work. Subscribe to it, and start the drag and drop procedure in it. For example:

 private void treeView1_ItemDrag(object sender, ItemDragEventArgs e) { if(e.Button == MouseButtons.Left) { treeView1.DoDragDrop(e.Item, DragDropEffects.Move); } } 

Now you can remove the DoDragDrop call from the MouseDown handler and forget about the bug click with the right click.


This is not the only surprise from DoDragDrop . After its activation, all mouse events are no longer processed until it is completed. This is most likely due to the fact that mouse events are transmitted to the window manager, and not to your program window, since DragDrop can drag objects between programs, and this requires an external context. But I didn’t dig deep into WinAPI, so perhaps this is not a bad topic for a separate issue .

  • It is !!!! Today is a very good day :). Thank you so much for your help - Alexander Muksimov
  • Once the author has accepted the answer, get a trace and an award) - Nick Volynkin