2017-08-02 2 views
1

J'ai une vue GridView comme vue réduite dans un contrôle SemanticZoom. Cette GridView utilise un DataTemplateSelector personnalisé en tant que ItemTemplateSelector. DataTemplateSelector renvoie un DataTemplate avec une couleur de premier plan différente, selon que le groupe contient ou non des éléments.UWP GridView ItemTemplateSelector dans SemanticZoom ne s'applique pas

Cependant, même si DataTemplateSelector semble fonctionner et renvoie le modèle correct, seul un modèle est utilisé par GridView et le texte est de la même couleur.

Voici le XAML du GroupedListView:

<UserControl 
    x:Class="GroupList.GroupList.GroupedListView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:GroupList.GroupList" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:data="using:GroupList.Model" 
    xmlns:wuxdata="using:Windows.UI.Xaml.Data" 
    mc:Ignorable="d"> 

    <UserControl.Resources> 
     <!-- Use a collection view source for content that presents itself as a list of items that can be grouped or sorted. Otherwise, you can use x:Bind 
     directly on the ListView's item source to for further optimization. Please see the AppUIBasics sample for an example of how to do this. --> 
     <CollectionViewSource x:Name="ContactsCVS" IsSourceGrouped="True" /> 

     <Style TargetType="TextBlock" x:Key="TileHeaderTextStyle" BasedOn="{StaticResource ProximaNovaSemiBold}"> 
      <Setter Property="FontSize" Value="54" /> 
      <Setter Property="Foreground" Value="White" /> 
      <Setter Property="FontWeight" Value="ExtraBold"/> 
      <Setter Property="FontStretch" Value="Expanded" /> 
     </Style> 

     <Style TargetType="TextBlock" x:Key="TileHeaderTextStyleGray" BasedOn="{StaticResource TileHeaderTextStyle}"> 
      <Setter Property="Foreground" Value="Khaki" /> 
     </Style> 

     <!-- When using x:Bind, you need to set x:DataType --> 
     <DataTemplate x:Name="ContactListViewTemplate" x:DataType="data:Contact"> 
      <Grid> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="*"/> 
        <RowDefinition Height="*"/> 
       </Grid.RowDefinitions> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="Auto"/> 
        <ColumnDefinition Width="*"/> 
       </Grid.ColumnDefinitions> 
       <Ellipse x:Name="Ellipse" 
         Grid.RowSpan="2" 
         Width ="32" 
         Height="32" 
         Margin="6" 
         VerticalAlignment="Center" 
         HorizontalAlignment="Center" 
         Fill="LightGray"/> 
       <TextBlock Grid.Column="1" 
          Text="{x:Bind Name}" 
          x:Phase="1" 
          Style="{ThemeResource BaseTextBlockStyle}" 
          Margin="12,6,0,0"/> 
       <TextBlock Grid.Column="1" 
          Grid.Row="1" 
          Text="{x:Bind Position}" 
          x:Phase="2" 
          Style="{ThemeResource BodyTextBlockStyle}" 
          Margin="12,0,0,6"/> 
      </Grid> 
     </DataTemplate> 
     <DataTemplate x:Key="GrayZoomedOutTemplate" x:DataType="wuxdata:ICollectionViewGroup"> 
      <TextBlock Text="{x:Bind Group.(data:GroupInfoList.Key)}" Margin="0,0,0,5" Style="{StaticResource TileHeaderTextStyleGray}" /> 
     </DataTemplate> 
     <DataTemplate x:Key="ZoomedOutTemplate" x:DataType="wuxdata:ICollectionViewGroup"> 
      <TextBlock Text="{x:Bind Group.(data:GroupInfoList.Key)}" Margin="0,0,0,5" Style="{StaticResource TileHeaderTextStyle}" /> 
     </DataTemplate> 
     <local:GroupEmptyOrFullSelector x:Key="GroupEmptyOrFullSelector" Empty="{StaticResource GrayZoomedOutTemplate}" Full="{StaticResource ZoomedOutTemplate}" /> 
    </UserControl.Resources> 
    <!--#region Navigation Panel --> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 
     <StackPanel Orientation="Vertical"> 
      <TextBlock Margin="15,0,0,0" Text="Paula's SemanticZoom Sandbox" Grid.Row="0" 
          VerticalAlignment="Center" 
          Style="{ThemeResource TitleTextBlockStyle}" /> 
      <Button x:Name="ZoomInOutBtn" Content="ABC↕" Click="ZoomInOutBtn_Click" Width="60" HorizontalAlignment="Center" BorderThickness="0" /> 
     </StackPanel> 
     <!--#endregion--> 
     <SemanticZoom x:Name="ZoomControl" Grid.Row="1"> 
      <SemanticZoom.ZoomedInView> 
       <GridView ItemsSource="{x:Bind ContactsCVS.View}" 
          ItemTemplate="{StaticResource ContactListViewTemplate}" 
          SelectionMode="Single" 
          ShowsScrollingPlaceholders="True"> 

        <GridView.GroupStyle> 
         <GroupStyle HidesIfEmpty="True"> 
          <GroupStyle.HeaderTemplate> 
           <DataTemplate x:DataType="data:GroupInfoList"> 
            <TextBlock Text="{x:Bind Key}" 
               Style="{ThemeResource TitleTextBlockStyle}" /> 
           </DataTemplate> 
          </GroupStyle.HeaderTemplate> 
         </GroupStyle> 
        </GridView.GroupStyle> 
       </GridView> 
      </SemanticZoom.ZoomedInView> 
      <SemanticZoom.ZoomedOutView> 
       <GridView ItemTemplateSelector="{StaticResource GroupEmptyOrFullSelector}" ScrollViewer.VerticalScrollBarVisibility="Disabled" Margin="0, 200" Width="475" ItemsSource="{x:Bind ContactsCVS.View.CollectionGroups}" SelectionMode="None" > 
       </GridView> 
      </SemanticZoom.ZoomedOutView> 
     </SemanticZoom> 
    </Grid> 
</UserControl> 

Et voici le DataTemplateSelector:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Controls.Primitives; 
using Windows.Foundation.Collections; 
using GroupList.Model; 

namespace GroupList.GroupList 
{ 
    /// <summary> 
    /// This determines whether or not the Group passed during binding is empty or not and allows selection 
    /// of the proper DataTemplate based on this value. 
    /// </summary> 
    class GroupEmptyOrFullSelector : DataTemplateSelector 
    { 
     private DataTemplate _full; 
     private DataTemplate _empty; 
     public DataTemplate Full 
     { 
      set { _full = value; } 
      get { return _full; } 
     } 
     public DataTemplate Empty 
     { 
      set { _empty = value; } 
      get { return _empty; } 
     } 


     protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) 
     { 

      var itemType = item.GetType(); 
      var isGroup = itemType.Name == "GroupInfoList"; 
      bool isEmpty = false; 
      GroupInfoList groupItem; 

      if (isGroup) 
      { 
       groupItem = item as GroupInfoList; 
       isEmpty = groupItem.Count == 0; 
      } 

      // Disable empty items 
      var selectorItem = container as SelectorItem; 
      if (selectorItem != null) 
      { 
       selectorItem.IsEnabled = !isEmpty; 
      } 

      if (isEmpty) 
      { 
       return Empty; 
      } 
      else 
      { 
       return Full; 
      } 
     } 
    } 
} 
+0

Votre code semble correct. Avez-vous vérifié votre source de date? Êtes-vous sûr d'avoir un groupe vide? – Scavenger

+0

Oui, il y a des groupes vides, je me suis assis dans le débogueur et vérifié chacun. – Paula

Répondre

0

Donc, voici était le problème:

Dans la liste DataTemplateSelector, même si un "objet" passé n'était pas un groupe, il est passé à la logique de sélection de modèle. Parfois, "l'objet" passé à votre fonction n'est pas un objet Group, mais plutôt un DependencyObject générique. Dans ce cas, la logique de sélection de modèle doit renvoyer un modèle par défaut, en renvoyant l'un des modèles spécifiques uniquement si "l'élément d'objet" est un objet Groupe. Ainsi, la nouvelle fonction ressemble à ceci:

protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) 
    { 

     var itemType = item.GetType(); 
     var isGroup = itemType.Name == "GroupInfoList"; 
     bool isEmpty = false; 
     GroupInfoList groupItem; 

     if (isGroup) 
     { 
      groupItem = item as GroupInfoList; 
      isEmpty = groupItem.Count == 0; 

      // Disable empty items 
      var selectorItem = container as SelectorItem; 
      if (selectorItem != null) 
      { 
       selectorItem.IsEnabled = !isEmpty; 
      } 

      if (isEmpty) 
      { 
       return Empty; 
      } 
      else 
      { 
       return Full; 
      } 

     } 

     return Full; 

    } 
+0

Je peux reproduire votre problème maintenant. Et cette réponse ne marche pas non plus. – Scavenger