In my WPF application using Prism in .NET 4.6, I have a User control with a ListBox on it. I want to attach a Context menu to the Items in the list box and when clicked, want to execute a command in the View Model.
The Context Menu is showing up alright. But nothing seems to happen when I click on the menu.
Here is my Xaml (removed all the code that are irrelevant).
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
x:Class="DynaProPOS.WPF.Views.UserAuthorization"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d" d:DesignHeight="600" d:DesignWidth="1000">
<Grid>
<ListBox Margin="15,5" x:Name="lbxGroups" Grid.Row="2" Grid.Column="2" Grid.RowSpan="1"
ItemsSource="{ Binding Groups }" SelectionMode="Single" SelectedValuePath="IdKey"
DisplayMemberPath="GroupName" SelectedItem="{Binding SelectedGroup, Mode=TwoWay}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Move to User Group" Command="{Binding AddGroupToUserGroupsCommand}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
</UserControl>
I also tried one of the following (found these samples on StackOverflow)
<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Move to User Group" Command="{Binding AddGroupToUserGroupsCommand}"
CommandParameter="{Binding}"/>
</ContextMenu>
and this:
<ContextMenu>
<MenuItem Header="Move to User Group" Command="{Binding AddGroupToUserGroupsCommand}"
CommandParameter="{Binding}"/>
and here is my View Model (again, all irrelevant code removed).
public class UserAuthorizationViewModel : BindableBase
{
private IAuthenticationService authService;
private User selectedUser;
private Users2Groups selectedUserGroup;
private Group selectedGroup;
private ObservableCollection<User> users;
private ObservableCollection<Users2Groups> users2Groups;
private ObservableCollection<Group> groups;
private ObservableCollection<Group> selectedGroups;
private ObservableCollection<Users2Groups> selectedUserGroups;
private ObservableCollection<Groups2Permissions> groupPermissions;
private ObservableCollection<Permission> allPermissions;
private IRegionManager regionMgr;
private ObservableCollection<Permission> selectedPermissions;
public DelegateCommand AddGroupToUserGroupsCommand { get; private set; }
public UserAuthorizationViewModel( IAuthenticationService _authService, IRegionManager _regionMgr )
{
authService = _authService;
regionMgr = _regionMgr;
AddGroupToUserGroupsCommand = new DelegateCommand( async () => await AddGroupToUserGroups() );
}
private async Task AddGroupToUserGroups()
{
if ( SelectedUser == null )
return;
foreach ( var sg in SelectedGroups )
{
if ( !UserGroups.Any( x => x.Group.IdKey == sg.IdKey ) )
{
var newUg = new Users2Groups();
newUg.User = SelectedUser;
newUg.Group = sg;
newUg.ObjectStateEnum = ObjectStateEnum.Added;
await Task.Run( () => UserGroups.Add( newUg ) );
}
}
}
}
Break point in the command handler never gets hit. Can somebody help me please?
EDIT OK. I found a way to make the context menu fire the attached command. But the problem is, now, the context menu appears anywhere by right clicking anywhere.
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
x:Class="DynaProPOS.WPF.Views.UserAuthorization"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d" d:DesignHeight="600" d:DesignWidth="1000">
<Grid>
<ListBox x:Name="lbxPermissions" HorizontalAlignment="Stretch" Grid.Row="2"
Grid.Column="3" Grid.RowSpan="3" Margin="15,10" VerticalAlignment="Stretch"
ItemsSource="{Binding AllPermissions}" SelectedValuePath="IdKey"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PermissionName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Add to Group" Command="{Binding AddPermissionToGroupsCommand}"/>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
</Grid>
What I need is to confine the context menu to appear only when I right click on a ListBox item. So, I found this sample code on SO which I used. This does make the context menu appear only on ListBox item. But the problem is, now, my command is not firing when I click the context menu item.
<ListBox x:Name="lbxPermissions" HorizontalAlignment="Stretch" Grid.Row="2"
Grid.Column="3" Grid.RowSpan="3" Margin="15,10" VerticalAlignment="Stretch"
ItemsSource="{Binding AllPermissions}" SelectedValuePath="IdKey"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding PermissionName}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Add to Group" Command="{Binding AddPermissionToGroupsCommand}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Any help? Anyone? Please?