2016-05-17 4 views
1

У меня есть GridView, который использует DataTemplateSelector. Он отлично работает, когда DataTemplateSelector установлен на GridView как так:Использование DataTemplateSelector с ItemContainerStyle

 <GridView x:Name="PayeesGridView" 
        IsItemClickEnabled="True" 
        ItemTemplateSelector="{StaticResource PayeeTemplateSelector}" 
        ItemsSource="{Binding FilteredPayees, 
             Mode=OneWay}" 
        Padding="5" 
        SelectionMode="None"> 

      <interactivity:Interaction.Behaviors> 
       <core:EventTriggerBehavior EventName="ItemClick"> 
        <core:CallMethodAction MethodName="GridViewItemClick" TargetObject="{Binding Mode=OneWay}" /> 
       </core:EventTriggerBehavior> 
      </interactivity:Interaction.Behaviors> 
      <GridView.ItemsPanel> 
       <ItemsPanelTemplate> 
        <ItemsWrapGrid x:Name="ItemWrapGrid" /> 
       </ItemsPanelTemplate> 
      </GridView.ItemsPanel> 

      <GridView.ItemContainerStyle> 
       <Style TargetType="GridViewItem"> 
        <Setter Property="Margin" Value="5" /> 
       </Style> 
      </GridView.ItemContainerStyle> 
     </GridView> 

Однако я пытаюсь установить DataTemplate внутри из ItemContainerStyle так, что я могу использовать VisualStateManager. Я попытался объявить это следующим образом:

 <GridView x:Name="PayeesGridView" 
        IsItemClickEnabled="True" 
        ItemsSource="{Binding FilteredPayees, 
             Mode=OneWay}" 
        Padding="5" 
        SelectionMode="None"> 

      <interactivity:Interaction.Behaviors> 
       <core:EventTriggerBehavior EventName="ItemClick"> 
        <core:CallMethodAction MethodName="GridViewItemClick" TargetObject="{Binding Mode=OneWay}" /> 
       </core:EventTriggerBehavior> 
      </interactivity:Interaction.Behaviors> 
      <GridView.ItemsPanel> 
       <ItemsPanelTemplate> 
        <ItemsWrapGrid x:Name="ItemWrapGrid" /> 
       </ItemsPanelTemplate> 
      </GridView.ItemsPanel> 

      <GridView.ItemContainerStyle> 
       <Style TargetType="GridViewItem"> 
        <Setter Property="Margin" Value="5" /> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate TargetType="GridViewItem"> 
           <Grid> 
            <Grid.Background> 
             <SolidColorBrush x:Name="GridBackground" Color="Transparent" /> 
            </Grid.Background> 

            <VisualStateManager.VisualStateGroups> 
             <VisualStateGroup x:Name="CommonStates"> 
              <VisualState x:Name="Normal" /> 
              <VisualState x:Name="PointerOver"> 
               <VisualState.Setters> 
                <Setter Target="GridBackground.Color" Value="Green" /> 
               </VisualState.Setters> 
               <Storyboard /> 
              </VisualState> 
              <VisualState x:Name="Pressed"> 
               <VisualState.Setters> 
                <Setter Target="GridBackground.Color" Value="#36B536" /> 
               </VisualState.Setters> 
               <Storyboard /> 
              </VisualState> 
             </VisualStateGroup> 
            </VisualStateManager.VisualStateGroups> 

            <ContentPresenter Content="{TemplateBinding Content}" 
                 ContentTemplate="{TemplateBinding ContentTemplate}" 
                 ContentTemplateSelector="{StaticResource PayeeTemplateSelector}" /> 
           </Grid> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style> 
      </GridView.ItemContainerStyle> 
     </GridView> 

ContentPresenter Использование и указания ContentTemplateSelector точно так же, как ItemTemplateSelector был на GridView. Выполняя это так, GridView просто отображает представление объекта для каждого Payee. VisualStates работает правильно, но он не использует DataTemplate s, которые я определил.

DataTemplates определены в Page.Resources так:

<DataTemplate x:Key="OpenPayeeDataTemplate" x:DataType="models:Payee"> 
     <Grid> 
      <Border Width="230" 
        Height="230" 
        Background="White" 
        BorderBrush="#36B536" 
        BorderThickness="4"> 
       <Grid Margin="5,0,5,0"> 
        <Image Width="160" 
          Height="160" 
          Source="{x:Bind LogoBase64, Converter={StaticResource Base64StringToImageSourceConverter}}" /> 
        <TextBlock VerticalAlignment="Top" 
           FontSize="14" 
           FontWeight="Bold" 
           Foreground="Black" 
           Text="{x:Bind CompanyName}" 
           TextAlignment="Left" 
           TextWrapping="WrapWholeWords" /> 
        <TextBlock VerticalAlignment="Bottom" 
           FontSize="12" 
           FontWeight="Bold" 
           Foreground="Black" 
           Text="{x:Bind AccountNickname}" 
           TextAlignment="Right" 
           TextWrapping="WrapWholeWords" /> 
       </Grid> 
      </Border> 
     </Grid> 
    </DataTemplate> 
    <DataTemplate x:Key="ClosedPayeeDataTemplate" x:DataType="models:Payee"> 
     <Grid> 
      <Border Width="230" 
        Height="230" 
        Background="White" 
        BorderBrush="#36B536" 
        BorderThickness="4"> 
       <Grid Margin="5,0,5,0"> 
        <Image Width="160" 
          Height="160" 
          Source="{x:Bind LogoBase64, Converter={StaticResource Base64StringToImageSourceConverter}}" /> 
        <TextBlock VerticalAlignment="Top" 
           FontSize="14" 
           FontWeight="Bold" 
           Foreground="Black" 
           Text="{x:Bind CompanyName}" 
           TextAlignment="Left" 
           TextWrapping="WrapWholeWords" /> 
        <TextBlock VerticalAlignment="Bottom" 
           FontSize="12" 
           FontWeight="Bold" 
           Foreground="Black" 
           Text="{x:Bind AccountNickname}" 
           TextAlignment="Right" 
           TextWrapping="WrapWholeWords" /> 
       </Grid> 
      </Border> 
      <Border Width="230" 
        Height="230" 
        Background="Gray" 
        Opacity="0.75" /> 
     </Grid> 
    </DataTemplate> 
    <converters:PayeeDataTemplateSelector x:Name="PayeeTemplateSelector" 
              ClosedPayeeDataTemplate="{StaticResource ClosedPayeeDataTemplate}" 
              OpenPayeeDataTemplate="{StaticResource OpenPayeeDataTemplate}" /> 

Кроме того, я попытался использовать VisualStateManager внутри DataTemplate с, но они не срабатывают, так что я должен использовать его внеDataTemplate, отсюда желание использовать ContentPresenter внутри ItemContainerStyle.

Я делаю что-то подобное с некоторыми ListViewItem, но они не используют DataTemplateSelector, поэтому я не сталкиваюсь с той же проблемой. Есть ли способ получить VisualStateManager для работы в пределах DataTemplate или получить DataTemplateSelector для работы в пределах ContentPresenter?

EDIT

Вот XAML я попытался положить в Styles/DataTemplates.xaml. Стиль применяется, но я не получаю никакого из VisualStates.

<DataTemplate x:Key="PaymentTemplate"> 
    <UserControl> 
     <Grid> 
      <VisualStateManager.VisualStateGroups> 
       <VisualStateGroup x:Name="CommonStates"> 
        <VisualState x:Name="Normal" /> 
        <VisualState x:Name="PointerOver"> 
         <VisualState.Setters> 
          <Setter Target="GridItemOverlay.Background" Value="Green" /> 
         </VisualState.Setters> 
        </VisualState> 
       </VisualStateGroup> 
      </VisualStateManager.VisualStateGroups> 

      <Border Width="450" 
        Height="Auto" 
        Background="White" 
        BorderBrush="#36B536" 
        BorderThickness="4" 
        CornerRadius="5"> 

       <Grid Margin="10,5,10,5"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition /> 
         <ColumnDefinition /> 
        </Grid.ColumnDefinitions> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="34" /> 
         <RowDefinition /> 
         <RowDefinition /> 
         <RowDefinition /> 
        </Grid.RowDefinitions> 
        <TextBlock Grid.Row="0" 
           Grid.Column="0" 
           Grid.ColumnSpan="2" 
           FontSize="26" 
           FontWeight="Bold" 
           Foreground="Black" 
           Text="{Binding AccountName}" 
           TextAlignment="Left" 
           TextWrapping="WrapWholeWords" /> 
        <TextBlock Grid.Row="1" 
           Grid.Column="0" 
           Foreground="Black" 
           Text="{Binding Path=Description}" 
           TextAlignment="Left" /> 
        <TextBlock Grid.Row="1" 
           Grid.Column="1" 
           Foreground="Black"> 
         <Run Text="Payment Amount: " /> 
         <Run Text="{Binding Path=PaymentAmount, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:N}'}" /> 
        </TextBlock> 
        <TextBlock Grid.Row="2" 
           Grid.Column="1" 
           Foreground="Black"> 
         <Run Text="Principal Amount: " /> 
         <Run Text="{Binding Path=PrincipalAmount, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:N}'}" /> 
        </TextBlock> 
        <TextBlock Grid.Row="3" 
           Grid.Column="0" 
           Foreground="Black"> 
         <Run Text="Payment Date: " /> 
         <Run Text="{Binding PaymentDate, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:MM/dd/yyyy}'}" /> 
        </TextBlock> 
        <TextBlock Grid.Row="3" 
           Grid.Column="1" 
           Foreground="Black"> 
         <Run Text="Interest Amount: " /> 
         <Run Text="{Binding Path=InterestAmount, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:N}'}" /> 
        </TextBlock> 
       </Grid> 
      </Border> 
      <Border x:Name="GridItemOverlay" 
        Background="Transparent" 
        Opacity="0.50" /> 
     </Grid> 
    </UserControl> 
</DataTemplate> 

В VisualState сек работа прекрасно, когда устанавливается непосредственно с помощью GridView.ItemContainerStyle установить Template, но не при попытке его из DataTemplate в отдельном файле ресурсов. Есть идеи?

ответ

2

Не уверен в селекторе шаблонов контента. Но ваша первоначальная мысль об использовании VisualStateManager внутри DataTemplates должна работать.

Есть одна вещь, которую вы пропустили, когда пытаетесь это сделать, вам нужно обернуть все внутри DataTemplate в теге UserControl! В противном случае VisualStateManager не будет работать.

Пример здесь: https://github.com/AppCreativity/Kliva/blob/master/src/Kliva/XAMLResources/DataTemplates.xaml#L21

+0

Я попытался достичь «VisualStateManager» таким образом, который вы используете в «Кливе», и я до сих пор не получаю никаких изменений. Я отправляю XAML на свой оригинальный пост, поэтому он отформатирован правильно ... –

+0

Странно сначала посмотреть свой DataTemplate xaml выглядит правильно:/ – Depechie

+0

Да, я тоже так думал. По крайней мере, мне удалось заставить его работать с шаблоном, отделенным от «VisualStateManager». Лучше, чем ничего, я полагаю. –

0

Я могу добиться того, что я хотел, установив ContentTemplate на ContentPresenter внутри моего ItemTemplate, как это:

<GridView.ItemContainerStyle> 
     <Style TargetType="GridViewItem"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="GridViewItem"> 
         <Grid> 
          <VisualStateManager.VisualStateGroups> 
           <VisualStateGroup x:Name="CommonStates"> 
            <VisualState x:Name="Normal" /> 
            <VisualState x:Name="PointerOver"> 
             <VisualState.Setters> 
              <Setter Target="GridItemOverlay.Background" Value="Green" /> 
             </VisualState.Setters> 
            </VisualState> 
           </VisualStateGroup> 
          </VisualStateManager.VisualStateGroups> 

          <ContentPresenter ContentTemplate="{StaticResource PaymentTemplate}" /> 
          <Border x:Name="GridItemOverlay" 
            Background="Transparent" 
            Opacity="0.50" /> 
         </Grid> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </GridView.ItemContainerStyle> 

И конечно, PaymentTemplate является a DataTemplate, определенный в DataTemplates.xaml. В идеале я хотел бы получить материал VisualStateManager вместе с самим DataTemplate, чтобы развязать XAML в моем View, но этот способ работает пока.

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