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

在WPF的列表视图分组中检索组名

首先,我想我已经知道为什么你的命令不开火了。

因为你在一个模板中,数据上下文已经改变了。因此,你的命令绑定应该是这样的:

<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的上下文菜单。

希望这对你有帮助!