如何添加选项以有选择地从ComboBox中删除项目?

时间:2014-01-13 14:20:13

标签: c# wpf xaml visualtreehelper

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

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

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

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

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

要点:

这就是我解决它的方法,最后(The credit belongs to Nawed Nabi Zada, who provided the main idea of "climbing" using the VisualTreeHelper.GetParent(...) to get the ComboBoxItem, in the accepted answer, below

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

(The "Icon Extractor" that fetches the icon from the system's DLL is from an old post of mine)

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

你也可以这样做:

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

答案 2 :(得分:0)

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

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

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

相关问题