Animate LongListSelectorItem Foreground on Hold in Windows Phone

痞子三分冷 提交于 2019-12-08 13:34:32

问题


I've been working my head a lot in the few past days on trying to acquire a nice foreground animation effect for the case of holding an item.

The Item template looks like this :

<DataTemplate>
    <StackPanel toolkit:TiltEffect.IsTiltEnabled="True" Hold="OnLongListSelectorItemHold">
        <toolkit:ContextMenuService.ContextMenu>
            <toolkit:ContextMenu>
                <toolkit:MenuItem Header="edit" />
                <toolkit:MenuItem Header="delete" />
            </toolkit:ContextMenu>
        </toolkit:ContextMenuService.ContextMenu>
        <TextBlock x:Name="SubjectTextBlock" Text="{Binding Subject}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Last modified :" Margin="15, 0, 5, 0" Foreground="LightGray" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock Text="{Binding LastModified}" Foreground="#989696" Style="{StaticResource PhoneTextNormalStyle}"/>
        </StackPanel>
    </StackPanel>
</DataTemplate>

I have tried multiple approaches, but I haven't managed to get a result from any of them.

I came across this nice MSDN post which shows multiple examples, but none of them could be really match my case because, the TextBlock Foregrounds I want to animate, refer to TextBlocks, inside a DataTemplate so I have problems with accessing a specific control inside the template.

For example, I tried this approach :

<phone:PhoneApplicationPage.Resources>
    <Storyboard x:Name="ItemHoldAnimation">
        <ColorAnimation Storyboard.TargetName="SubjectTextBlock" 
                        Storyboard.TargetProperty="Foreground"
                        From="White" To="{StaticResource PhoneAccentColor}" Duration="0:00:04"/>
    </Storyboard>
</phone:PhoneApplicationPage.Resources>

And then to fire it from the Hold event handler :

var storyboard = Resources["ItemHoldAnimation"] as Storyboard;
storyboard.Begin();

But it fails because TargetName="SubjectTextBlock" is not accessible because it is inside the DataTemplate...

I have also tried an approach I found for WPF with EventTriggers, like this :

<StackPanel toolkit:TiltEffect.IsTiltEnabled="True" Hold="OnLongListSelectorItemHold">
    <StackPanel.Triggers>
        <EventTrigger RoutedEvent="StackPanel.Hold">
            <BeginStoryboard Storyboard="{StaticResource ItemHoldAnimation}"/>
        </EventTrigger>
    </StackPanel.Triggers>
    ...
</StackPanel>

but it gives COM exception...

MS.Internal.WrappedException: Error HRESULT E_FAIL has been returned from a call to a COM component. ---> System.Exception: Error HRESULT E_FAIL has been returned from a call to a COM component.

A lot just to animate font when the LongListSelector item is hold...

What is the approach on solving this issue?


回答1:


You should define the storyboard inside the DataTemplate, also the target proeprty need to be modified because ColorAnimation work on a Color property not a brush. Finally IsZoomEnabled="False" need also to be set because otherwise the ContextMenu implementation take a snapshot of the element and show this static image while the context menu is open so the animation will not be visible (the alternative is to modify the source code of ContextMenu to delay the opening of the context menu after your animation is done) Something like this should work:

<DataTemplate x:Key="dataTemplate">
        <StackPanel toolkit:TiltEffect.IsTiltEnabled="True" Hold="OnLongListSelectorItemHold">
            <StackPanel.Resources>
                <Storyboard x:Name="ItemHoldAnimation">
                    <ColorAnimation Storyboard.TargetName="SubjectTextBlock" 
                    Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
                    From="White" To="{StaticResource PhoneAccentColor}" Duration="0:00:04"/>
                </Storyboard>
                <Storyboard x:Name="MenuClosedAnimation">
                    <ColorAnimation Storyboard.TargetName="SubjectTextBlock" 
                Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
                From="{StaticResource PhoneAccentColor}" To="White" Duration="0:00:04"/>
                </Storyboard>
            </StackPanel.Resources>
            <toolkit:ContextMenuService.ContextMenu>
                <toolkit:ContextMenu IsZoomEnabled="False" Closed="ContextMenu_OnClosed">
                    <toolkit:MenuItem Header="edit" />
                    <toolkit:MenuItem Header="delete" />
                </toolkit:ContextMenu>
            </toolkit:ContextMenuService.ContextMenu>
            <TextBlock x:Name="SubjectTextBlock" Text="Test" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Last modified :" Margin="15, 0, 5, 0" Foreground="LightGray" Style="{StaticResource PhoneTextNormalStyle}"/>
                <TextBlock Text="{Binding LastModified}" Foreground="#989696" Style="{StaticResource PhoneTextNormalStyle}"/>
            </StackPanel>
        </StackPanel>
    </DataTemplate>

and here is the hold method:

private void OnLongListSelectorItemHold(object sender, GestureEventArgs e)
    {
        FrameworkElement fe = sender as FrameworkElement;
        var storyboard = fe.Resources["ItemHoldAnimation"] as Storyboard;
        storyboard.Begin();
    }

private void ContextMenu_OnClosed(object sender, RoutedEventArgs e)
    {
        ContextMenu eleme=sender as ContextMenu;
        FrameworkElement fe = eleme.Owner as FrameworkElement;
        var storyboard = fe.Resources["MenuClosedAnimation"] as Storyboard;
        storyboard.Begin();
    }


来源:https://stackoverflow.com/questions/19076942/animate-longlistselectoritem-foreground-on-hold-in-windows-phone

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!