如何在WPF上从Listbox中右键单击项目并打开菜单

14

我有一个带有文件的Listbox,我想要能够右键单击并打开一个菜单(如删除)以从Listbox中删除文件。

目前,我在Listbox内右键单击项目后拥有这个功能:

private void listBoxFiles_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{

}

我在XAML中实现了右键单击后的删除菜单。

          <ListBox.ContextMenu>
                <ContextMenu>                                                        
                    <MenuItem Header="Delete"/>
                </ContextMenu>
            </ListBox.ContextMenu>

从我的ListBox中删除文件的函数:

private void MenuItemDelete_Click(object sender, RoutedEventArgs e)
{            
    if (listBoxFiles.SelectedIndex == -1)
    {
        return;
    }

    //string filePath = (listBoxFiles.SelectedItem).ToString();
    int index = listBoxFiles.SelectedIndex;
    listBoxFiles.Items.RemoveAt(index);
}
2个回答

39

你已经有了一个带有你的标记的上下文菜单。

如果你想执行某个操作,其中一种方法是在菜单的Click函数中检查点击了哪个项目。例如,你有以下的列表框:

<ListBox Name="someListBox">
    <ListBox.ContextMenu>
         <ContextMenu>
             <MenuItem Header="Delete" Click="MenuItemDelete_Click"/>
         </ContextMenu>
    </ListBox.ContextMenu>

    <ListBoxItem>...</ListBoxItem>
    <ListBoxItem>...</ListBoxItem>
    <ListBoxItem>...</ListBoxItem>

</ListBox>

下一个可能的函数是:

private void MenuItemDelete_Click(object sender, RoutedEventArgs e)
{
    if (someListBox.SelectedIndex == -1) return;

    // Hypothetical function GetElement retrieves some element
    var element = GetElement(someListBox.SelectedIndex);

    // Hypothetical function DeleteElement
    DeleteElement(element);
}

更新于2012年3月5日:

这里是另一种列表框的变体。你可以向列表框项添加上下文菜单,而不是仅限于列表框本身。例如:

<ListBox Name="someListBox" MouseDown="someListBox_MouseDown">
    <ListBox.Resources>

        <!--Defines a context menu-->
        <ContextMenu x:Key="MyElementMenu">
            <MenuItem Header="Delete" Click="MenuItemDelete_Click"/>
        </ContextMenu>

        <!--Sets a context menu for each ListBoxItem in the current ListBox-->
        <Style TargetType="{x:Type ListBoxItem}">
             <Setter Property="ContextMenu" Value="{StaticResource MyElementMenu}"/>
        </Style>

    </ListBox.Resources>
    <ListBoxItem>...</ListBoxItem>
    <ListBoxItem>...</ListBoxItem>
    <ListBoxItem>...</ListBoxItem>
</ListBox>

1) 当您在列表框的空白区域中单击时,此函数将取消选择所有项目:

private void someListBox_MouseDown(object sender, MouseButtonEventArgs e)
{
    someListBox.UnselectAll();
}

2) 当您单击列表框项时,它会变为蓝色。当您右键单击列表框项时,它仍然是蓝色的,但如果出现上下文菜单,则列表框项会变为灰色,可能是因为此项失去了焦点。

3) 删除功能正常工作:

private void MenuItemDelete_Click(object sender, RoutedEventArgs e)
{
    if (someListBox.SelectedIndex == -1)
    {
        return;
    }

    someListBox.Items.RemoveAt(someListBox.SelectedIndex);
}

我想在菜单中添加3个功能(菜单中的每个选项都有不同的功能),所以仍然需要检查点击了哪个项目?并且我不理解函数s MenuItemDelete_Click中的最后两行。 - user979033
因为所有列表元素共享上下文菜单,所以您应该检查点击了哪个项目。最后2行不是必要的,我只是写它们来展示一些示例。您应该确定单击了哪个元素,并执行某些操作。 - Taras Feschuk
如果您想检索所点击元素的文本值,可以编写以下代码: string elementText = ((ListBoxItem)someListBox.SelectedItem).Content.ToString(); - Taras Feschuk
错误:无法将类型为“System.String”的对象强制转换为类型“System.Windows.Controls.ListBoxItem”。 - user979033
首先感谢您的帮助!我认为这种方式可以让文件在变成蓝色(鼠标按下)后仍然保留在列表框中,然后右键单击,选择删除选项。这不是正常的行为,您确定没有其他方法可以以这种方式删除文件吗? - user979033
显示剩余3条评论

2

当你编写代码时,不需要使用 listBoxFiles_PreviewMouseRightButtonDown

<ListBox>
            <ListBox.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Delete"></MenuItem>
                </ContextMenu>
            </ListBox.ContextMenu>
        </ListBox>

右键后已经可以正常工作了。


好的,现在我该如何“捕获”我点击的文件名(路径)? - user979033
我想在菜单中添加3个功能(菜单中的每个选项将具有不同的功能),因此仍然需要检查哪个项目被点击了吗? 而且我没有理解函数s MenuItemDelete_Click中的最后2行。 - user979033
错误:无法将类型为“System.String”的对象强制转换为类型“System.Windows.Controls.ListBoxItem”。 - user979033
现在没问题了,但我有另外几个问题:1.为什么在Listbox中按下每个项目都会将其状态从选定(蓝色)更改为未选定,如果选择了文件并在Listbox上的空白处按下,则文件仍保持选定状态?2.我实现了一个函数,如果我在Listbox上按右键并在菜单中按删除,则该项将从我的Listbox中删除,但只有在之前未选择文件时才会发生这种情况,我的意思是,如果我在Listbox中按下项目,然后右键单击并删除文件,则文件将保留在Listbox中而不被删除,请查看我的更新。 - user979033

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接