【问题标题】:Add Selected effect on LongListSelector with XAML使用 XAML 在 LongListSelector 上添加 Selected 效果
【发布时间】:2014-10-10 09:12:27
【问题描述】:

我有带有 GroupHeaderTemplate 和 ItemTemplate 的 LongListSelector。

我想在组中的选定项目上添加“选定”效果。例如,我的名为 RightArrow 的元素会变成灰色(现在是蓝色)。

我试图用 Expression Blend 做到这一点,但效果并不适用于所选项目,而是适用于每个项目。

<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>

【问题讨论】:

标签: xaml windows-phone-8 expression-blend


【解决方案1】:

据我所知,问题在于您将情节提要应用于整个 LongListSelector 控件而不是单个项目。您的VisualStateManager 应放入ItemTemplate (DataTemplate)。

不幸的是,盒子似乎没有提供任何挂钩,因此您必须使用 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作为一个小帮手来轻松获取control的孩子。

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。它可能与示例略有不同,因为我想确保它能够正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多