【问题标题】:Retrieve GroupName in Listview Grouping in WPF在 WPF 中的 Listview 分组中检索 GroupName
【发布时间】:2016-10-14 13:51:29
【问题描述】:

我已经设置了一个带有分组的 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>

【问题讨论】:

  • 据我所知,它不可能在样式中使用混合行为。但也许你可以使用这个解决方法:How to add a Blend Behavior in a Style Setter
  • 我已经尝试了您链接中的解决方案,但它似乎不起作用..您知道尝试访问所选组的其他方法吗?
  • 也许您可以尝试将PreviewMouseRightButtonDown 作为事件。您绑定了 ContextMenuMouseRightButtonDown 事件。如果首先调用 ContextMenu 并设置 e.Handled,则永远不会调用其他事件。也许这行得通。

标签: c# wpf xaml listview mvvm


【解决方案1】:

首先,我想我已经弄清楚了为什么你的命令没有触发。

由于您在模板中,因此 DataContext 已更改。因此,您的 CommandBinding 应如下所示:

<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}, Path=DataContext.OnCategorySelected}" CommandParameter="{Binding}"/>

另外,你的 CommandParameter 不应该是Name,因为你最后只会得到一个字符串而不是整个对象。

如果你使用我上面的代码,你会得到整个CollectionViewGroup。在上述CollectionViewGroup 中,您将找到该组中的所有项目。如果您对仅获取 Groupname 感到满意,您当然可以继续实施。

我真的不明白您为什么使用ContextMenu 以及它的作用(因为您没有发布该代码),但如果您对如何在这样的 ContextMenu 中显示分组项目感兴趣,您可以这样做像这样:

<Expander IsExpanded="False"  Background="#FFEBEBEB" BorderThickness="0" >
          <Expander.ContextMenu>
                   <ContextMenu ItemsSource="{Binding Items}"/>
          </Expander.ContextMenu>
</Expander>

既然我们现在知道了,我们要处理什么(仍然是CollectionViewGroup),我们可以将它的 Items 设置为 ContextMenu 的 ItemsSource。

希望这会有所帮助!

【讨论】:

  • 这就像一个魅力!问题在于绑定。我有一个小问题,当在 ListView 绑定期间创建类别时,即使我没有右键单击该类别,也会调用该命令。你有什么建议吗?
  • 请注意您的答案:名称属于对象类型,它反映了组创建中使用的相同类型(在我的情况下为枚举类型)
  • 解决了!问题出在 CommandParameter="{Binding} 中。仅绑定“名称”会使问题消失!我正试图奖励你赏金,但 SO 说我必须等待 5 小时......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-26
  • 1970-01-01
  • 2017-12-23
相关资源
最近更新 更多