Как добавить опцию для выборочного удаления элементов из ComboBox?
У меня есть 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);
}
("Icon Extractor", который выбирает значок из системной DLL, взят из моего старого поста)
3 ответа
Вы также можете сделать это следующим образом:
<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);
}
}
Поместите это ContextMenu для каждого ComboBoxItem вместо самого 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;
}
Чтобы найти элементы списка, вы можете использовать флажок в шаблоне элементов списка, чтобы пользователь мог проверить элементы, которые он / она хочет удалить.
Если ваш комбинированный список привязан к данным, вам придется отфильтровать источник данных вашего комбинированного списка, т. Е. При щелчке контекстного меню вам придется удалить элементы, проверенные пользователем, из источника данных вашего комбинированного списка, а затем повторно связать комбинированный список с источником данных.
Если у вас нет связанного списка данных с привязкой к данным, то в контекстном меню щелкните просто циклически переберите элементы комбинированного списка и удалите элементы, которые были проверены пользователем.