28

我知道如何制作一个在我右键单击 listView 时弹出的 contextMenu,我想要的是当我右键单击item时它会弹出。我正在尝试制作聊天服务器和客户端,现在...现在我想在右键单击已连接客户端的项目时查看客户端信息。

我怎样才能做到这一点?

4

8 回答 8

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

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

于 2012-11-18T06:44:15.557 回答
8

您将不得不使用 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
        }

    }

}
于 2012-11-18T06:40:35.353 回答
4

您可以通过使用并提供与该选定项目相关的上下文菜单来触发其中的事件MouseDown或其中MouseUp的事件。ListViewMouseButton.RightListView.Hittest

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

于 2012-11-18T06:38:46.733 回答
2

完全解决方案

  • 当用户右键单击 listView 中的项目时弹出。
  • 如果列表没有项目,请避免异常。
  • 如果选择了一个项目,则显示删除和编辑选项。

在此处输入图像描述

代码:

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;
}
于 2019-06-11T03:39:46.773 回答
0

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

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

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

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

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 可以容纳对象,这意味着 selected_lvi 可以是您的对象的类型。只是转换为正确的类型。

我希望这有帮助。

最好的祝福,

麦克风

于 2013-06-05T14:29:22.430 回答
0

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

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

例子 :

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);
    }
}

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

于 2017-10-20T14:21:09.610 回答
0
    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;
        }
    }
于 2018-10-27T05:21:13.047 回答
-1

使用 DevExpress 20.2 核心... Winforms。这类似于在 GridView 中处理菜单项。

Private WithEvents _menuViewLabelitem As MenuItem
    Private Sub lvShipTracking_MouseClick(sender As Object, e As MouseEventArgs) Handles lvShipTracking.MouseClick

    If e.Button = MouseButtons.Right Then

        If lvShipTracking.FocusedItem IsNot Nothing AndAlso lvShipTracking.FocusedItem.Bounds.Contains(e.Location) = True Then
            Dim m As ContextMenu = New ContextMenu()
            _menuViewLabelitem = New MenuItem("View Label")

            AddHandler Click, AddressOf Handle_ViewLabel

            m.MenuItems.Add(_menuViewLabelitem)
            m.Show(lvShipTracking, New Point(e.X, e.Y))
        End If
    End If

End Sub

Private Sub Handle_ViewLabel(sender As Object, e As EventArgs) Handles _menuViewLabelitem.Click
    MsgBox("it worked!")
End Sub
于 2021-06-24T19:00:17.430 回答