在WPF的列表视图分组中检索组名
本文关键字:检索 视图 WPF 列表 | 更新日期: 2023-09-27 18:13:15
我已经设置了一个具有分组的ListView,我想在MVVM中右键单击组时检索GroupName。我已经在我的组样式上放置了一个ContextMenu
,并且我试图使用System.Windows.Interactivity中的EventToCommand来获取底层项目。
这里是相关的部分:
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="False" Template="{StaticResource CustomizedExpander}" Background="#FFEBEBEB" BorderThickness="0" ContextMenu="{StaticResource GroupContextMenu}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseRightButtonDown">
<i:InvokeCommandAction Command="{Binding Path=OnCategorySelected}" CommandParameter="{Binding Name}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Expander.Header>
<StackPanel Orientation="Horizontal">
<!--N.B. The "Name" property is part of the CollectionViewSource-->
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="#FF767676" VerticalAlignment="Bottom" />
<TextBlock Text="{Binding ItemCount}" Foreground="#FF454545" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
<TextBlock Text=" item(s)" Foreground="#FF767676" FontStyle="Italic" VerticalAlignment="Bottom" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
我不知道这样做是否正确,但似乎命令根本没有被触发。
任何建议吗?
更新:整件事比我想象的要简单得多。交互部分根本不需要。固定绑定就足以在显示上下文菜单时获得基础类别:<ListView ItemsSource="{Binding Modifications}" SelectedItem="{Binding SelectedItem}">
<ListView.Resources>
<ContextMenu x:Key="ItemContextMenu">
<MenuItem Header="Execute" Command="{Binding Path=DataContext.OnExecuteScript, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Background="WhiteSmoke" Visibility="{Binding CanExecute, Converter={StaticResource BooleanToVisibilityConverter}}" />
<MenuItem Header="Execute up to this" Command="{Binding Path=DataContext.OnExecuteScriptUpToThis, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Background="WhiteSmoke" Visibility="{Binding CanOnlyBeExecutedSequentially, Converter={StaticResource BooleanToVisibilityConverter}}" />
<MenuItem Header="Drop" Command="{Binding Path=DataContext.OnExecuteDrop, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Visibility="{Binding Drop, Converter={StaticResource BooleanToVisibilityConverter}}" Background="WhiteSmoke" />
<MenuItem Header="Dump" Command="{Binding Path=DataContext.OnExecuteDump, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" Visibility="{Binding CanDump, Converter={StaticResource BooleanToVisibilityConverter}}" Background="WhiteSmoke" />
</ContextMenu>
<ContextMenu x:Key="GroupContextMenu">
<MenuItem Header="Dump all" Command="{Binding Path=DataContext.OnExecuteDumpAll, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}}" CommandParameter="{Binding Name}" Background="WhiteSmoke" />
</ContextMenu>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Type" Width="120" DisplayMemberBinding="{Binding Type}" />
<GridViewColumn Header="Object Name" Width="Auto" DisplayMemberBinding="{Binding DisplayName}" />
<GridViewColumn Header="" Width="50">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Deploy}" IsHitTestVisible="False" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Object Name" Width="300" DisplayMemberBinding="{Binding ObjectName}" />
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource MetroListViewItem}" >
<Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Drop}" Value="True">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="ContextMenu" Value="{StaticResource GroupContextMenu}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander IsExpanded="False" Template="{StaticResource CustomizedExpander}" Background="#FFEBEBEB" BorderThickness="0">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<!--N.B. The "Name" property is part of the CollectionViewSource-->
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="#FF767676" VerticalAlignment="Bottom" />
<TextBlock Text="{Binding ItemCount}" Foreground="#FF454545" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
<TextBlock Text=" item(s)" Foreground="#FF767676" FontStyle="Italic" VerticalAlignment="Bottom" />
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
首先,我想我已经知道为什么你的命令不开火了。
因为你在一个模板中,数据上下文已经改变了。因此,你的命令绑定应该是这样的:
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}, Path=DataContext.OnCategorySelected}" CommandParameter="{Binding}"/>
另外,你的CommandParameter不应该是Name
,因为你只会在最后得到一个字符串,而不是整个对象。
如果你使用我上面的代码,你会得到整个CollectionViewGroup
代替。在上述CollectionViewGroup
中,您将找到组中的所有项目。如果您对只获得Groupname感到满意,您当然可以继续执行您的实现。
我真的不明白为什么你使用ContextMenu
和它做什么(因为你没有发布的代码),但如果你有兴趣如何在这样一个上下文菜单中显示分组项目,你可以这样做:
<Expander IsExpanded="False" Background="#FFEBEBEB" BorderThickness="0" >
<Expander.ContextMenu>
<ContextMenu ItemsSource="{Binding Items}"/>
</Expander.ContextMenu>
</Expander>
既然我们现在知道,我们要处理的(它仍然是一个CollectionViewGroup
),我们可以设置它的Items作为ItemsSource的上下文菜单。
希望这对你有帮助!