2014-10-10 45 views
1

我有LongListSelector和GroupHeaderTemplate和ItemTemplate。使用XAML在LongListSelector上添加選定的效果

我想添加'選定'效果在組中的選定項目。例如,我的稱爲RightArrow的元素可以變灰(現在是藍色)。

我試圖用Expression Blend做到這一點,但效果不適用於選定的項目,但對每個項目都適用。

Preview

<phone:LongListSelector x:Name="longListSelectorState" RenderTransformOrigin="-0.893,0.033" ItemTemplate="{StaticResource StateItemTemplate}" JumpListStyle="{StaticResource StateJumpListStyle}" LayoutMode="List" IsGroupingEnabled="true" HideEmptyGroups ="true" GroupHeaderTemplate="{StaticResource StateGroupHeaderTemplate}" Style="{StaticResource LongListSelectorStyle}"/> 

<Style x:Key="LongListSelectorStyle" TargetType="phone:LongListSelector"> 
    <Setter Property="Background" Value="Transparent"/> 
    <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="phone:LongListSelector"> 
       <Grid Background="{TemplateBinding Background}" d:DesignWidth="480" d:DesignHeight="800"> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="ScrollStates"> 
          <VisualStateGroup.Transitions> 
           <VisualTransition GeneratedDuration="00:00:00.5"/> 
          </VisualStateGroup.Transitions> 
          <VisualState x:Name="Scrolling"> 
           <Storyboard> 
            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VerticalScrollBar"/> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="Selected"> 
           <Storyboard> 
            <DoubleAnimation Duration="0" To="48" Storyboard.TargetProperty="(Control.FontSize)" 
              Storyboard.TargetName="textBlock" /> 

            <ColorAnimation Duration="0" To="Red" Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="textBlock" /> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="NotScrolling"/> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <Grid Margin="{TemplateBinding Padding}"> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="*"/> 
          <ColumnDefinition Width="auto"/> 
         </Grid.ColumnDefinitions> 
         <ViewportControl x:Name="ViewportControl" HorizontalContentAlignment="Stretch" VerticalAlignment="Top"/> 
         <ScrollBar x:Name="VerticalScrollBar" Grid.Column="1" Margin="4,0,4,0" Opacity="0" Orientation="Vertical"/> 
        </Grid> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

<DataTemplate x:Key="StateItemTemplate"> 
    <StackPanel VerticalAlignment="Top"> 
     <Grid x:Name="grid"> 
      <StackPanel x:Name="stackPanel" Orientation="Vertical" HorizontalAlignment="Left"> 
       <TextBlock x:Name="textBlock" Text="{Binding ItemName}" Foreground="#DE000000" FontFamily="Segoe WP SemiLight" FontSize="29.333" Padding="0,5,0,0" Margin="4,0,0,0" /> 
       <TextBlock x:Name="textBlock1" Text="{Binding SubItemNames}" Visibility="{Binding HasSubItems, Converter={StaticResource BoolVisibilityConverter}}" Foreground="#DE000000" FontFamily="Segoe WP SemiLight" FontSize="21.333" Padding="0,4" LineHeight="2.667" /> 
      </StackPanel> 
      <Ellipse x:Name="RightArrow" Visibility="{Binding HasSubItems, Converter={StaticResource BoolVisibilityConverter}}" Fill="#FF0202EA" Stroke="Black" HorizontalAlignment="Right" Width="44" Height="44"/> 
     </Grid> 
    </StackPanel> 
</DataTemplate> 
+0

看看這個:http://stackoverflow.com/questions/18325889/how-to-highlight-a-selected-item-in-longlistselector – Kulasangar 2014-10-10 15:37:27

回答

1

從我看到的問題是,你申請的故事板整個LongListSelector控制,而不是單個項目。您的VisualStateManager應放入ItemTemplateDataTemplate)。

不幸的是,似乎沒有從箱子中提供鉤子,因此您必須使用VisualStateManager.GoToState方法手動管理物品狀態。

首先,您應該刪除分配給LongListSelectorSelected狀態的故事板,因爲這部分會影響整個列表。

然後你應該創建兩個視覺狀態的簡單控制:NormalSelected

<UserControl x:Class="PhoneApp2.CustomLongListSelectorItem" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    FontFamily="{StaticResource PhoneFontFamilyNormal}" 
    FontSize="{StaticResource PhoneFontSizeNormal}" 
    Foreground="{StaticResource PhoneForegroundBrush}" 
    d:DesignHeight="480" d:DesignWidth="480"> 

    <Grid x:Name="LayoutRoot"> 
     <VisualStateManager.VisualStateGroups> 
      <VisualStateGroup x:Name="CommonStates"> 
       <VisualState x:Name="Normal"/> 
       <VisualState x:Name="Selected"> 
        <Storyboard> 
         <ColorAnimation Duration="0" To="Red" 
             Storyboard.TargetProperty="(Control.Foreground).(SolidColorBrush.Color)" 
             Storyboard.TargetName="ContentTextBlock" /> 
        </Storyboard> 
       </VisualState> 
      </VisualStateGroup> 
     </VisualStateManager.VisualStateGroups> 

     <StackPanel Margin="12,12"> 
      <TextBlock x:Name="ContentTextBlock" Text="{Binding}" TextWrapping="Wrap"/> 
     </StackPanel> 
    </Grid> 
</UserControl> 

然後將此控件添加到您的DataTemplate如下:

<phone:LongListSelector x:Name="ListSelector" SelectionChanged="HandleSelectionChanged"> 
    <phone:LongListSelector.ItemTemplate> 
     <DataTemplate> 
      <phoneApp2:CustomLongListSelectorItem/> 
     </DataTemplate> 
    </phone:LongListSelector.ItemTemplate> 
</phone:LongListSelector> 

最後,你將有很少的代碼添加到您的網頁的代碼隱藏,將管理您的自定義控制的狀態。 基本上,你需要實施HandleSelectionChanged方法和GetItemsRecursive作爲一個小幫手來輕鬆獲得控制的孩子。

private void HandleSelectionChanged(Object sender, SelectionChangedEventArgs e) 
{ 
    var userControlList = new List<CustomLongListSelectorItem>(); 
    GetItemsRecursive(ListSelector, ref userControlList); 

    // Selected. 
    if (e.AddedItems.Count > 0 && e.AddedItems[0] != null) 
    { 
     foreach (var userControl in userControlList) 
     { 
      if (e.AddedItems[0].Equals(userControl.DataContext)) 
      { 
       VisualStateManager.GoToState(userControl, "Selected", true); 
      } 
     } 
    } 

    // Unselected. 
    if (e.RemovedItems.Count > 0 && e.RemovedItems[0] != null) 
    { 
     foreach (var userControl in userControlList) 
     { 
      if (e.RemovedItems[0].Equals(userControl.DataContext)) 
      { 
       VisualStateManager.GoToState(userControl, "Normal", true); 
      } 
     } 
    } 
} 

public static void GetItemsRecursive<T>(DependencyObject parents, ref List<T> objectList) where T : DependencyObject 
{ 
    var childrenCount = VisualTreeHelper.GetChildrenCount(parents); 

    for (int i = 0; i < childrenCount; i++) 
    { 
     var child = VisualTreeHelper.GetChild(parents, i); 

     if (child is T) 
     { 
      objectList.Add(child as T); 
     } 

     GetItemsRecursive(child, ref objectList); 
    } 
} 

上面提供的代碼大部分來自此示例Highlight a selected item in the LongListSelector on WP8。這可能與樣本略有不同,因爲我希望確保這種方式可以正常工作。