简体   繁体   English

ListBox中的上下文菜单命令未触发

[英]Context Menu command in ListBox not firing

In my WPF application using Prism in .NET 4.6, I have a User control with a ListBox on it. 在.NET 4.6中使用Prism的WPF应用程序中,我有一个带有ListBox的User控件。 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). 这是我的Xaml(删除了所有不相关的代码)。

    <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) 我还尝试了以下方法之一(在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. 我需要将上下文菜单限制为仅在右键单击ListBox项时才显示。 So, I found this sample code on SO which I used. 因此,我在所用的SO上找到了此示例代码。 This does make the context menu appear only on ListBox item. 这确实使上下文菜单仅出现在ListBox项上。 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? 请?

Bind the Tag property of the ListBoxItem to the view model and bind to the command using the PlacementTarget property of the ContextMenu : ListBoxItemTag属性绑定到视图模型,并使用ContextMenuPlacementTarget属性绑定到命令:

<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="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType=ListBox}}" />
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu>
                        <MenuItem Header="Move to User Group"
                                  Command="{Binding PlacementTarget.Tag.AddGroupToUserGroupsCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

This should work assuming that the AddGroupToUserGroupsCommand property belongs to the same view model class as the Groups property. 假设AddGroupToUserGroupsCommand属性与Groups属性属于同一个视图模型类,这应该可以工作。

ListBox Tag property needs Binding. ListBox Tag属性需要绑定。 Since you are trying to do the PlacementTarget.Tag for command Binding. 由于您尝试为命令绑定执行PlacementTarget.Tag。

 <ListBox Margin="15,5" x:Name="lbxGroups" Grid.Row="2" 
Tag={Binding} 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 DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                            <MenuItem Header="Move to User Group" Command="{Binding AddGroupToUserGroupsCommand}"
                                         CommandParameter="{Binding}"/>
                        </ContextMenu>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM