2013-11-12 2 views
4

Я пытаюсь показать разные группы в Listview, которые содержат расширитель и заголовок. Однако я не хочу, чтобы моя группа SecondLevel отображала заголовок, если группа содержит только 1 элемент. Поскольку это было бы довольно неудобно. Мой код:WPF GroupStyle только для групп с более чем 1 элементом

<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

+1

Как и ide note, это не будет работать должным образом. На изображении вы можете видеть, что ваши элементы Expander заставляют элементы неправильно выравниваться с заголовками столбцов. Рассмотрим преобразователь, который вычисляет разницу в координате X ведущего столбца и содержимое расширителя и применяет отрицательный запас. Это все равно не даст вам идеального контроля, но это приведет к контенту. – Gusdor

ответ

7
  1. Для обоих стилей расколоть ControlTemplate в 2, один с расширителем и один с вне.

  2. Создать преобразователь, который проверяет, если размер группы (ваша группа типа CollectionViewGroup)

    return yourGroup.Items.Count > 1 
    
  3. Поместите DataTrigger, как показано ниже в каждом стиле, который проверяет размерные группы с помощью преобразователя (ваш DataContext ваша группа, так что привязка Binding = "{Binding}"

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> 

Edit:

* стоимость преобразователя будет сама группа (типа 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(); 
    } 
} 
+0

Не могли бы вы пойти немного в конвертер, который вам нужен? Я не совсем уверен, как реализовать эту вещь. Большое спасибо – Xeun

+0

@Xeun см. Редактировать. –

+0

Я думаю, что проверка в конвертере должна читать 'return grp.ItemCount> 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> 

Смежные вопросы