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

时间:2017-11-09 21:31:39

标签: c# wpf mvvm listbox contextmenu

在我使用Prism in .NET 4.6的WPF应用程序中,我有一个带有ListBox的User控件。我想将上下文菜单附加到列表框中的项目,单击时,想要在视图模型中执行命令。

上下文菜单显示正常。但是当我点击菜单时,似乎没有任何事情发生。

这是我的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>

我还尝试了以下其中一种(在StackOverflow上找到这些样本)

                        <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                            <MenuItem Header="Move to User Group" Command="{Binding AddGroupToUserGroupsCommand}"
                                         CommandParameter="{Binding}"/>
                        </ContextMenu>

和此:

<ContextMenu>
<MenuItem Header="Move to User Group" Command="{Binding AddGroupToUserGroupsCommand}" 
                                        CommandParameter="{Binding}"/>

这是我的视图模型(同样,删除了所有不相关的代码)。

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

    }
}

命令处理程序中的断点永远不会被命中。有人可以帮帮我吗?

修改 好。我找到了一种方法来使上下文菜单触发附加的命令。但问题是,现在,通过右键单击任何地方都可以显示上下文菜单。

<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>

我需要的是限制上下文菜单仅在我右键单击ListBox项时出现。所以,我在SO上找到了这个示例代码。这确实使上下文菜单仅出现在ListBox项上。但问题是,现在,当我单击上下文菜单项时,我的命令没有触发。

        <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>

有任何帮助吗?任何人?请?

2 个答案:

答案 0 :(得分:1)

Tag的{​​{1}}属性绑定到视图模型,并使用ListBoxItem的{​​{1}}属性绑定到该命令:

PlacementTarget

假设ContextMenu属性属于与<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> 属性相同的视图模型类,则应该可以正常工作。

答案 1 :(得分:0)

ListBox标签属性需要绑定。因为您正在尝试为命令绑定执行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>