C# 显示 ListView 中项目的上下文菜单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13437889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 08:33:19  来源:igfitidea点击:

Showing a Context Menu for an item in a ListView

c#winforms

提问by Daaksin

Now, please, I know how to make a contextMenu that pops up when I right click on a listView, what I want is for it to pop up when I right click on an item. I am trying to make a chat server and client, and now... Now I want to view client info when I right click on a connected client's item. Now how can I do this?

现在,拜托,我知道如何制作一个在我右键单击 listView 时弹出的上下文菜单,我想要的是当我右键单击一个项目时它会弹出。我正在尝试制作聊天服务器和客户端,现在...现在我想在我右键单击已连接客户端的项目时查看客户端信息。现在我该怎么做?

Thanks!

谢谢!

采纳答案by Rashedul.Rubel

private void listView1_MouseClick(object sender, MouseEventArgs e)
{            
    if (e.Button == MouseButtons.Right)
    {
        if (listView1.FocusedItem.Bounds.Contains(e.Location))
        {
            contextMenuStrip1.Show(Cursor.Position);
        }
    } 
}

You can put connected client information in the contextMenuStrip1. and when you right click on a item, you can show the information from that contextMenuStrip1.

您可以将连接的客户端信息放在 contextMenuStrip1 中。当您右键单击一个项目时,您可以显示该 contextMenuStrip1 中的信息。

回答by Mr_Green

You can trigger MouseDownor MouseUpevent of ListViewin which if MouseButton.Rightthen grab the selected Item by using ListView.Hittestand give the Context menu related to that Selected Item.

您可以触发MouseDownMouseUp事件ListView,其中,如果MouseButton.Right然后用抢的选择项目ListView.Hittest,并给予相关的是所选项目的右键菜单。

For more clear info you can go through this link

有关更清晰的信息,您可以通过此链接

回答by Mark Hall

You are going to have to use the ListViews Context Menu, but change it according to the ListView Item you right click on.

您将不得不使用 ListViews 上下文菜单,但根据您右键单击的 ListView 项对其进行更改。

private void listView1_MouseDown(object sender, MouseEventArgs e)
{
    bool match = false;

    if (e.Button == System.Windows.Forms.MouseButtons.Right)
    {
        foreach (ListViewItem item in listView1.Items)
        {
            if (item.Bounds.Contains(new Point(e.X, e.Y)))
            {
                MenuItem[] mi = new MenuItem[] { new MenuItem("Hello"), new MenuItem("World"), new MenuItem(item.Name) };
                listView1.ContextMenu = new ContextMenu(mi);
                match = true;
                break;
            }
        }
        if (match)
        {
            listView1.ContextMenu.Show(listView1, new Point(e.X, e.Y));
        }
        else
        {
            //Show listViews context menu
        }

    }

}

回答by Mike

The topic is quite old, but I'll leave my solution for reference.

这个话题已经很老了,但我会留下我的解决方案以供参考。

In xaml ListView definition put your context menu:

在 xaml ListView 定义中放置上下文菜单:

<ListView Name="m_list" >
    <ListView.ContextMenu>
        <ContextMenu>
            <MenuItem Header="menuItem1" Click="ContextMenuItem1Clicked" />
            <MenuItem Header="menuItem2" Click="ContextMenuItem2Clicked" />
        </ContextMenu>
    </ListView.ContextMenu>
...
</ListView>

Now, in the code, define two event handlers that will fire up on clicking respective menu item:

现在,在代码中,定义两个将在单击相应菜单项时触发的事件处理程序:

private void ContextMenuItem1Clicked(object sender, RoutedEventArgs e)
{
    // handle the event for the selected ListViewItem accessing it by
    ListViewItem selected_lvi = this.m_list.SelectedItem as ListViewItem;
}

private void ContextMenuItem2Clicked(object sender, RoutedEventArgs e)
{
    // handle the event for the selected ListViewItem accessing it by
    ListViewItem selected_lvi = this.m_list.SelectedItem as ListViewItem;
}

ListView can accommodate objects, which means that the selected_lvi can be of type of your object. Just cast is to proper type.

ListView 可以容纳对象,这意味着 selected_lvi 可以是您的对象类型。Just cast 是正确的类型。

I hope this helps.

我希望这有帮助。

Best regards,

此致,

Mike

麦克风

回答by brainsandwich

I've found a new solution that doesn't rely on mouse event handlers. The ContextMenu has a "Popup" event handler.

我找到了一个不依赖鼠标事件处理程序的新解决方案。ContextMenu 有一个“Popup”事件处理程序。

On popup, I add the relevant menu items I need depending on my context.

在弹出窗口中,我根据上下文添加所需的相关菜单项。

Example :

例子 :

private MenuItem[] standardMenuItems;
private MenuItem[] selectedMenuItems;

public SomePanel() {
    InitializeComponent();

    // These are list of menu items (name / callback) that will be
    // chosen depending on some context
    standardMenuItems = new MenuItem[] { new MenuItem("New", OnNew) };
    selectedMenuItems = new MenuItem[] { new MenuItem("Delete", OnDelete), new MenuItem("Edit", OnEdit) };

    ContextMenu contextMenu = new ContextMenu();

    // begin with "standard items"
    contextMenu.MenuItems.AddRange(standardMenuItems);
    listview.ContextMenu = contextMenu;

    // add the popup handler
    contextMenu.Popup += OnMenuPopup;
}

// Called right before the menu comes up
private void OnMenuPopup(object sender, EventArgs e) {
    ContextMenu menu = sender as ContextMenu;
    if (menu == null)
        return;

    // If an item was selected, display Delete and Edit options
    if (listview.SelectedItems.Count > 0) {
        menu.MenuItems.Clear();
        menu.MenuItems.AddRange(selectedMenuItems);
    }

    // Else display only the New option
    else {
        menu.MenuItems.Clear();
        menu.MenuItems.AddRange(standardMenuItems);
    }
}

I'm not fluent enough in C# and Winforms to be sure there are no drawbacks to this technique, but it's an alternative to relying on mouse events (what if / does the context menu can appear on other keyboard or mouse event ?)

我对 C# 和 Winforms 不够流利,无法确保这种技术没有缺点,但它是依赖鼠标事件的替代方法(如果/是否上下文菜单可以出现在其他键盘或鼠标事件上?)

回答by emalware

    private void contextMenuStripExport_Opening(object sender, System.ComponentModel.CancelEventArgs e)
    {
        if (exportview.SelectedItems.Count <= 0)
        {
            uploadToolStripMenuItem.Visible = false;
            exportToolStripMenuItem.Visible = false;
        }
        else
        {
            uploadToolStripMenuItem.Visible = true;
            exportToolStripMenuItem.Visible = true;
        }
    }

回答by kkasp

Fully solution

全面解决

  • Pops up when user right click on a item in a listView.
  • Avoid an exception if the list have no items.
  • If an item was selected, display Delete and Edit options.
  • 当用户右键单击 listView 中的项目时弹出。
  • 如果列表没有项目,请避免异常。
  • 如果选择了某个项目,则显示删除和编辑选项。

enter image description here

在此处输入图片说明

Code:

代码:

private void Form1_Load(object sender, EventArgs e)
{
    listView1.MouseUp += new MouseEventHandler(listView1_MouseClick);

}

private void listView1_MouseClick(object sender, MouseEventArgs e)
{
    string id = "xxx";//extra value

    if (e.Button == MouseButtons.Right)
    {
        if (listView1.FocusedItem != null && listView1.FocusedItem.Bounds.Contains(e.Location) == true)
        {
            ContextMenu m = new ContextMenu();
            MenuItem cashMenuItem = new MenuItem("編輯");
            cashMenuItem.Click += delegate (object sender2, EventArgs e2) {
                ActionClick(sender, e, id);
            };// your action here 
            m.MenuItems.Add(cashMenuItem);

            MenuItem cashMenuItem2 = new MenuItem("-");
            m.MenuItems.Add(cashMenuItem2);

            MenuItem delMenuItem = new MenuItem("刪除");
            delMenuItem.Click += delegate (object sender2, EventArgs e2) {
                DelectAction(sender, e, id);
            };// your action here
            m.MenuItems.Add(delMenuItem);

            m.Show(listView1, new Point(e.X, e.Y));

        }
    }
}

private void DelectAction(object sender, MouseEventArgs e, string id)
{
    ListView ListViewControl = sender as ListView;
    foreach (ListViewItem eachItem in ListViewControl.SelectedItems)
    {
        // you can use this idea to get the ListView header's name is 'Id' before delete
        Console.WriteLine(GetTextByHeaderAndIndex(ListViewControl, "Id", eachItem.Index) );
        ListViewControl.Items.Remove(eachItem);
    }
}

private void ActionClick(object sender, MouseEventArgs e, string id)
{
    //id is extra value when you need or delete it
    ListView ListViewControl = sender as ListView;
    foreach (ListViewItem tmpLstView in ListViewControl.SelectedItems)
    {
        Console.WriteLine(tmpLstView.Text);
    }

}

public static string GetTextByHeaderAndIndex(ListView listViewControl, string headerName, int index)
{
    int headerIndex = -1;
    foreach (ColumnHeader header in listViewControl.Columns)
    {
        if (header.Name == headerName)
        {
            headerIndex = header.Index;
            break;
        }
    }
    if (headerIndex > -1)
    {
        return listViewControl.Items[index].SubItems[headerIndex].Text;
    }
    return null;
}