I am trying to figure out how I can bind the ContextMenu of the Button that is being added in the ItemsControl I have. Basically, I'm wanting to be able to right click on a button and remove it from the observable collection that sits on my viewmodel. I understand that ContextMenu's are not part of the VisualTree, so using RelativeSource to walk up the tree to find my DataContext hasn't been useful to me.
The end goal of what I want to do is Bind the Command on the MenuItem to the RemoveCommand on my ViewModel and then pass in the Content property of the Button that you right click on so that I can remove it from the observable collection.
Any help on this would be greatly appreciated.
Model:
public class Preset
{
public string Name { get; set; }
}
ViewModel:
public class SettingsWindowViewModel
{
public ObservableCollection<Preset> MyPresets { get; } = new ObservableCollection<Preset>();
private ICommand _plusCommand;
public ICommand PlusCommand => _plusCommand ?? (_plusCommand = new DelegateCommand(AddPreset));
private ICommand _removeCommand;
public ICommand RemoveCommand => _removeCommand ?? (_removeCommand = new DelegateCommand<string>(RemovePreset));
private void AddPreset()
{
var count = MyPresets.Count;
MyPresets.Add(new Preset {Name = $"Preset{count+1}"});
}
private void RemovePreset(string name)
{
var preset = MyPresets.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.CurrentCultureIgnoreCase));
if (preset!= null)
{
MyPresets.Remove(preset);
}
}
}
XAML:
<Window x:Class="WpfTesting.Esper.Views.SettingsWindow"
x:Name="MainSettingsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:WpfTesting.Esper.ViewModels"
mc:Ignorable="d"
Title="SettingsWindow" Height="470" Width="612">
<Window.DataContext>
<viewModels:SettingsWindowViewModel/>
</Window.DataContext>
<Window.Resources>
<Style BasedOn="{StaticResource {x:Type MenuItem}}" TargetType="{x:Type MenuItem}" x:Key="PopupMenuItem">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border>
<ContentPresenter ContentSource="Header"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="35"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<Button Width="70" Content="Load"/>
<Button Width="70" Content="Save As"/>
<ItemsControl ItemsSource="{Binding MyPresets}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="70" Content="{Binding Name}">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Style="{StaticResource PopupMenuItem}" Header="Remove">
<!--
I need to set up binding a Command to a method on the DataContext of the Window, and I need to pass in the Content of the Button that is the parent of the ContextMenu
-->
</MenuItem>
</ContextMenu>
</Button.ContextMenu>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Width="20" Background="Transparent" BorderBrush="Transparent" Content="+" FontSize="21.333" HorizontalAlignment="Center" VerticalAlignment="Center" Command="{Binding PlusCommand}"/>
</StackPanel>
</Grid>
</Window>