C# WinForm拖拽ToolStripMenuItem至ListView并获取对象引用求助
Let's walk through how to resolve your issue step by step. The core problem here is twofold: you're incorrectly trying to cast the DragDrop event sender (which is always the ListView) to a ToolStripMenuItem, and the drag data wasn't being packaged properly to preserve the original menu item reference.
Step 1: Correct the Drag Data Packaging
When starting the drag operation, explicitly package the ToolStripMenuItem into a DataObject to ensure it's carried through the drag-and-drop process. This avoids any implicit data handling that might lose the reference.
Update your mnulevel3_MouseDown event handler:
void mnulevel3_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { ToolStripMenuItem menuItem = sender as ToolStripMenuItem; if (menuItem != null) { // Create a data object to hold our menu item reference DataObject dragData = new DataObject(); dragData.SetData(typeof(ToolStripMenuItem), menuItem); // Start the drag operation menuItem.DoDragDrop(dragData, DragDropEffects.Copy); } } }
Step 2: Validate Drag Data in DragEnter
Only allow the drop if the incoming data contains a ToolStripMenuItem to avoid invalid operations:
private void listView1_DragEnter(object sender, DragEventArgs e) { // Check if the drag data is our ToolStripMenuItem if (e.Data.GetDataPresent(typeof(ToolStripMenuItem))) { e.Effect = DragDropEffects.Copy; } else { e.Effect = DragDropEffects.None; } }
Step 3: Retrieve Original Menu Item in DragDrop
Pull the ToolStripMenuItem from the drag data, create your ListViewItem, and store the original menu item in the ListViewItem.Tag property so you can access it later:
private void listView1_DragDrop(object sender, DragEventArgs e) { try { if (e.Data.GetDataPresent(typeof(ToolStripMenuItem))) { ToolStripMenuItem originalMenuItem = (ToolStripMenuItem)e.Data.GetData(typeof(ToolStripMenuItem)); if (originalMenuItem != null) { ListViewItem lvItem = new ListViewItem(originalMenuItem.Text); // Store the original menu item reference for later access lvItem.Tag = originalMenuItem; listView1.Items.Add(lvItem); } } } catch (Exception ex) { MessageBox.Show($"Error during drop: {ex.Message}"); } }
Step 4: Access Original Menu Item When Selecting ListViewItem
To access the original ToolStripMenuItem properties when a ListViewItem is selected, use the Tag property:
private void listView1_SelectedIndexChanged(object sender, EventArgs e) { if (listView1.SelectedItems.Count > 0) { ListViewItem selectedItem = listView1.SelectedItems[0]; ToolStripMenuItem originalMenu = selectedItem.Tag as ToolStripMenuItem; if (originalMenu != null) { // Access any property from the original menu item MessageBox.Show($"Original Menu Text: {originalMenu.Text}\nTag Value: {originalMenu.Tag}"); } } }
Why Your Original Code Failed
- You tried casting the
DragDropevent sender (which is theListViewcontrol) toToolStripMenuItem—this will always throw a cast error. - The drag data wasn't explicitly packaged, which could lead to the
e.Data.GetDatacall returning null (especially with right-click drag operations, which have different default behavior than left-click).
Content of the question来源于stack exchange,提问作者Priya

