WPF GroupStyle仅适用于包含多个项目的组

时间:2013-11-12 10:19:47

标签: c# wpf listview

我试图在Listview中显示包含扩展器和标头的不同组。但是,如果组仅包含1个项目,我不希望我的SecondLevel组显示标题。 因为这会非常不方便。 我的代码:

<Window x:Class="ListViewGrouping.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:listViewGrouping="clr-namespace:ListViewGrouping"
    Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
    <listViewGrouping:GroupItemStyleSelector x:Key="groupItemStyleSelector"/>
    <!-- Style for the first level GroupItem -->
        <Style x:Key="FirstLevel" TargetType="{x:Type GroupItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type GroupItem}">
                        <Expander IsExpanded="True">
                            <Expander.Header>
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>
                                    <TextBlock Grid.Column="0" Margin="3.5,0" Text="{Binding Name}" TextBlock.FontWeight="Bold"/>
                                    <TextBlock Grid.Column="1" Margin="3.5,0" Text="Elements:"/>
                                    <TextBlock Grid.Column="2" Margin="3.5,0" Text="{Binding ItemCount}"/>
                                </Grid>
                            </Expander.Header>
                            <ItemsPresenter />
                        </Expander>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <!-- Style for the second level GroupItem -->
        <Style x:Key="SecondLevel" TargetType="{x:Type GroupItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type GroupItem}">
                        <Expander IsExpanded="True" Margin="15,0,0,0">
                            <Expander.Header>
                                <TextBlock Text="{Binding Name}" TextBlock.FontWeight="Bold"/>
                            </Expander.Header>
                            <ItemsPresenter />
                        </Expander>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <ListView Name="mailView" ItemsSource="{Binding}">
            <ListView.GroupStyle>
                <GroupStyle ContainerStyleSelector="{StaticResource groupItemStyleSelector}" />
            </ListView.GroupStyle>
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}"/>
                    <GridViewColumn Header="Subject" DisplayMemberBinding="{Binding Subject}"/>
                    <GridViewColumn Header="Sender" DisplayMemberBinding="{Binding Sender}"/>
                    <GridViewColumn Header="Support-ID" DisplayMemberBinding="{Binding Support_ID}"/>
                    <GridViewColumn Header="Supporter" DisplayMemberBinding="{Binding Supporter}"/>
                    <GridViewColumn Header="Received" DisplayMemberBinding="{Binding ReceivedDate}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>

代码背后:

    private void createMailList()
    {
        _mails.Add(new Mail("LIC", "Lizenz geht nicht", "Xeun", "LIC.2013.01.10.002", "Xeun", "25.09.2013"));
        _mails.Add(new Mail("CD", "Alles doof", "Xeun", "CD.2013.01.10.002", "Xeun", "25.09.2013"));
        _mails.Add(new Mail("CD", "Re:Alles doof", "Xeun", "CD.2013.01.10.002", "Xeun", "25.09.2013"));
        _mails.Add(new Mail("CD", "CD kaputt", "Xeun", "CD.2013.01.10.003", "Xeun", "25.09.2013"));
        _mails.Add(new Mail("CD", "Geht nicht", "Xeun", "CD.2013.01.10.001", "Xeun", "25.09.2013"));
        _mails.Add(new Mail("LIC", "Kaputt", "Xeun", "LIC.2013.01.10.001", "Xeun", "25.09.2013"));
    }
    public MainWindow()
    {

        InitializeComponent();

        createMailList();
        DataContext = _mails;
        ICollectionView view = CollectionViewSource.GetDefaultView(_mails);
        PropertyGroupDescription groupDescription = new PropertyGroupDescription("ID");
        view.GroupDescriptions.Add(groupDescription);
        view.GroupDescriptions.Add(new PropertyGroupDescription("Support_ID"));
    }

}
public class GroupItemStyleSelector : StyleSelector
{
    public override Style SelectStyle(object item, DependencyObject container)
    {
        Style s;

        CollectionViewGroup group = item as CollectionViewGroup;
        Window window = Application.Current.MainWindow;

        if (!group.IsBottomLevel)
        {
            s = window.FindResource("FirstLevel") as Style;
        }
        else
        {
            s = window.FindResource("SecondLevel") as Style;
        }

        return s;
    }
}

我希望我能够很好地解释我的问题 - 我附上了小应用程序的屏幕截图 - 标记为红色的组只包含一个项目,不应该显示为组。 screenshot

2 个答案:

答案 0 :(得分:9)

  1. 对于这两种样式,将ControlTemplate拆分为2,一个使用扩展器,另一个使用扩展。

  2. 创建一个转换器,用于检查组大小(您的组是否为CollectionViewGroup类型)

     return yourGroup.Items.Count > 1 
    
  3. 在每种样式中放置一个DataTrigger,如下所示,通过转换器检查组大小 (您的DataContext是您的组,因此绑定是Binding =“{Binding}”

  4. xaml:

     <ControlTemplate TargetType="{x:Type GroupItem}" x:Key="withExpander">
         <Expander IsExpanded="True">
             <Expander.Header>
                   .....
             </Expander.Header>
             <ItemsPresenter />
          </Expander>
      </ControlTemplate>
    
    
      <ControlTemplate TargetType="{x:Type GroupItem}" x:Key="withOutExpander">        
            <ItemsPresenter />          
      </ControlTemplate>
    
      <Style x:Key="FirstLevel" TargetType="{x:Type GroupItem}">
          <Setter Property="Template" Value="{StaticResource withExpander}" />
    
          <Style.Triggers>
              <DataTrigger Binding="{Binding , Converter={StaticResource GroupSizeToExpanderConverter}" Value="False">
                      <Setter Property="Template" Value="{StaticResource withOutExpander}"/>
              </DataTrigger>    
          </Style.Triggers>
      </Style>
    

    编辑:

    *转换器值将是Group本身(类型为CollectionViewGroup)

    转换器:

    public class GroupSizeToExpanderConverter: IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            CollectionViewGroup grp = (CollectionViewGroup)value;
            return grp.Items.Count() > 1; // ALTERNATIVLY grp.ItemCount;             
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

答案 1 :(得分:0)

这是我的解决方案

<GroupStyle>
<GroupStyle.ContainerStyle>
    <Style TargetType="{x:Type GroupItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Grid>
                        <Expander IsExpanded="True">
                            <Expander.Style>
                                <Style TargetType="Expander">
                                    <Setter Property="Visibility" Value="Visible"></Setter>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding ItemCount}" Value="1">
                                            <Setter Property="Visibility" Value="Collapsed"></Setter>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Expander.Style>
                            <Expander.Header>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Gray" FontSize="22" VerticalAlignment="Bottom" />
                                    <TextBlock Text="{Binding ItemCount}" FontSize="22" Foreground="Green" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
                                    <TextBlock Text=" item(s)" FontSize="22" Foreground="Silver" FontStyle="Italic" VerticalAlignment="Bottom" />
                                </StackPanel>
                            </Expander.Header>
                            <Border BorderBrush="LightBlue" BorderThickness="2" Margin="0 2">
                                <ItemsPresenter />
                            </Border>
                        </Expander>
                        <ItemsPresenter>
                            <ItemsPresenter.Style>
                                <Style TargetType="ItemsPresenter">
                                    <Setter Property="Visibility" Value="Collapsed"></Setter>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding ItemCount}" Value="1">
                                            <Setter Property="Visibility" Value="Visible"></Setter>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </ItemsPresenter.Style>
                        </ItemsPresenter>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</GroupStyle.ContainerStyle>