2014-01-13 137 views
1

我有一個顯示字符串的ComboBox。我如何添加一個選項來從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)

+0

雖然從轉移你目前的策略,你可能會考慮處理'DEL'鍵。 –

+0

@MichaelPerrenoud,它不會非常用戶友好。 – Tar

+0

使用[SelectedItem](http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.selecteditem%28v=vs.110%29.aspx)?在ComboBox上的ContextMenu似乎對我來說是錯誤的,儘管... – UIlrvnd

回答

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

對於定位組合框項目,您可以使用複選框在組合框的項目模板,以便用戶可以檢查的項目,他/她想要刪除。

如果你的組合框是數據綁定的,那麼你將不得不過濾你的組合框的數據源,即在上下文菜單上點擊你將不得不刪除用戶從你的組合框的數據源檢查的項目,然後重新綁定組合框與數據源。

如果您沒有數據綁定組合框,則在上下文菜單上單擊,只需循環遍歷組合框項目並刪除用戶檢查的項目。

+0

我相信問題是如何獲取用戶想要刪除的項目。 – UIlrvnd

1

看跌的ContextMenu每個ComboBoxItem而不是組合框本身:

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

你也可以把在DataTemplate中或生成它從後面的代碼,這取決於你如何填充組合框。然後在菜單項的Click事件處理程序,你可以做如下,以獲取用戶選擇ComboBoxItem

private void MenuItem_OnClick(object sender, RoutedEventArgs e) 
{ 
    var menuItem = (MenuItem)sender; 
    var ctxMenu = (ContextMenu)menuItem.Parent; 
    var comboBoxItem = (ComboBoxItem) ctxMenu.PlacementTarget; 
} 
+0

非常好的主意! – Tar

相關問題