2

我有一个ComboBox显示字符串的。如何添加从ComboBox列表中删除某些项目的选项?我试过:

<ComboBox.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Remove" Click="MenuItem_OnClick"></MenuItem>
    </ContextMenu>
</ComboBox.ContextMenu>

但我不知道如何找到用户选择的项目:

private void MenuItem_OnClick(object sender, RoutedEventArgs e) {
    /* ... ??? ... */
}

我不介意在每个项目旁边放一些图标,单击时会删除其相关项目,但不知道该怎么做..

概括:

这就是我最终解决它的方法(信用属于Nawed Nabi Zada,谁提供了“攀登”的主要思想,在VisualTreeHelper.GetParent(...)接受ComboBoxItem的答案中,在下面

<ComboBox IsEditable="True" Name="RemotePathComboBox" VerticalAlignment="Center"
          SelectionChanged="RemotePathComboBoxOnSelectionChanged"
          Grid.Column="1" Margin="0,6" KeyUp="HostNameOrIPAddress_OnKeyUp">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <DockPanel>
                <Button Click="RemoveRemotePathItem_Click" Margin="5" DockPanel.Dock="Left">
                    <Image Source="{Binding Converter={StaticResource iconExtractor}, ConverterParameter=%WinDir%\\System32\\shell32.dll|131}"/>
                </Button>
                <TextBlock Name="ItemTextBlock" VerticalAlignment="Center" Text="{Binding Path=Path}"></TextBlock>
            </DockPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

代码隐藏:

private void RemoveRemotePathItem_Click(object sender, RoutedEventArgs e) {
    var depObj = sender as DependencyObject;

    while (!(depObj is ComboBoxItem)) {
        if (depObj == null) return;
        depObj = VisualTreeHelper.GetParent(depObj);
    }

    var comboBoxItem = depObj as ComboBoxItem;
    var item = comboBoxItem.Content as RemotePathItem;

    _remotePathsList.Remove(item);
    RemotePathComboBox_SelectIndexWithoutChangingList(0);
}

(从系统的 DLL 中获取图标的“图标提取器”来自我的一篇旧帖子)

4

3 回答 3

2

你也可以这样做:

<Window x:Class="RemoveItemsFromComboBox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ComboBox x:Name="CbxItems" VerticalAlignment="Top" HorizontalAlignment="Left" Width="250">
        <ComboBox.ContextMenu>
            <ContextMenu>
                <MenuItem x:Name="MenuItem" Header="Delete" Click="MenuItem_OnClick"></MenuItem>
            </ContextMenu>
        </ComboBox.ContextMenu>
        <TextBlock Text="Item 1"/>
        <TextBlock Text="Item 2"/>
        <TextBlock Text="Item 3"/>
        <TextBlock Text="Item 4"/>
    </ComboBox>
</Grid>

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        CbxItems.PreviewMouseRightButtonDown += OnPreviewMouseRightButtonDown;
    }


    private void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        var comboBoxItem = VisualUpwardSearch(e.OriginalSource as DependencyObject);

        if (comboBoxItem == null) return;
        comboBoxItem.IsSelected = true;
        e.Handled = true;
    }

    private ComboBoxItem VisualUpwardSearch(DependencyObject source)
    {
        while (source != null && !(source is ComboBoxItem))
            source = VisualTreeHelper.GetParent(source);

        return source as ComboBoxItem;
    }

    private void MenuItem_OnClick(object sender, RoutedEventArgs e)
    {
        CbxItems.Items.Remove(CbxItems.SelectedItem);
    }
}
于 2014-01-13T15:14:36.880 回答
1

为每个 ComboBoxItem 放置 ContextMenu 而不是 ComboBox 本身:

<ComboBoxItem.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Remove" Click="MenuItem_OnClick"></MenuItem>
    </ContextMenu>
</ComboBoxItem.ContextMenu>

您还可以将它放在 DataTemplate 中或从后面的代码中生成它,具体取决于您填充 ComboBox 的方式。然后在菜单项的单击事件处理程序中,您可以执行以下操作来选择用户ComboBoxItem

private void MenuItem_OnClick(object sender, RoutedEventArgs e)
{
    var menuItem = (MenuItem)sender;
    var ctxMenu = (ContextMenu)menuItem.Parent;
    var comboBoxItem = (ComboBoxItem) ctxMenu.PlacementTarget;
}
于 2014-01-13T14:55:17.020 回答
0

为了定位组合框项目,您可以使用组合框项目模板中的复选框,以便用户可以检查他/她要删除的项目。

如果您的组合框是数据绑定的,那么您将必须过滤组合框的数据源,即在上下文菜单上单击您必须从组合框的数据源中删除用户检查的项目,然后将组合框与数据源重新绑定。

如果您没有数据绑定组合框,则在上下文菜单上单击只需循环组合框项目并删除用户检查的项目。

于 2014-01-13T14:39:38.270 回答