ListBox 中的上下文菜单命令未触发
Context Menu command in ListBox not firing
在 .NET 4.6 中使用 Prism 的 WPF 应用程序中,我有一个带有 ListBox 的用户控件。我想将上下文菜单附加到列表框中的项目,单击时,想在视图模型中执行命令。
上下文菜单显示正常。但是当我点击菜单时似乎没有任何反应。
这是我的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>
我还尝试了以下其中一项(在 Whosebug 上找到了这些示例)
<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>
我需要的是将上下文菜单限制为仅在我右键单击列表框项目时出现。所以,我在我使用的 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>
有什么帮助吗?任何人?请?
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>
将ListBoxItem
的Tag
属性绑定到视图模型,使用ContextMenu
的PlacementTarget
属性绑定到命令=]:
<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>
假设 AddGroupToUserGroupsCommand
属性 与 Groups
属性.
属于同一视图模型 class,这应该可以工作
在 .NET 4.6 中使用 Prism 的 WPF 应用程序中,我有一个带有 ListBox 的用户控件。我想将上下文菜单附加到列表框中的项目,单击时,想在视图模型中执行命令。
上下文菜单显示正常。但是当我点击菜单时似乎没有任何反应。
这是我的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>
我还尝试了以下其中一项(在 Whosebug 上找到了这些示例)
<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>
我需要的是将上下文菜单限制为仅在我右键单击列表框项目时出现。所以,我在我使用的 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>
有什么帮助吗?任何人?请?
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>
将ListBoxItem
的Tag
属性绑定到视图模型,使用ContextMenu
的PlacementTarget
属性绑定到命令=]:
<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>
假设 AddGroupToUserGroupsCommand
属性 与 Groups
属性.