I want to create marquee effect in WP8 application.
To accomplish this I placed StackPanel inside ScrollViewer and I'm trying to use DoubleAnimation on TranslateTransform.X property.
Code:
<phone:PhoneApplicationPage.Resources>
<Storyboard x:Name="Scroll" RepeatBehavior="Forever" AutoReverse="True">
<DoubleAnimation From="0" To="100" Storyboard.TargetName="transform" Storyboard.TargetProperty="X" Duration="0:0:5" />
</Storyboard>
</phone:PhoneApplicationPage.Resources>
<Grid x:Name="LayoutRoot">
...
<ScrollViewer Height="80" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Hidden">
<StackPanel Orientation="Horizontal">
<StackPanel.RenderTransform>
<TranslateTransform x:Name="transform" />
</StackPanel.RenderTransform>
<Image Source="/Assets/logo1.png"></Image>
<Image Source="/Assets/logo2.png"></Image>
<Image Source="/Assets/logo3.png"></Image>
<Image Source="/Assets/logo4.png"></Image>
<Image Source="/Assets/logo5.png"></Image>
</StackPanel>
</ScrollViewer>
</Grid>
Unfortunately when calling Scroll.Begin() from code-behind in page Loaded event handler I'm getting exception: System.InvalidOperationException: Cannot resolve TargetName transform.
What I'am doing wrong?
Animation runs when I place StackPanel directly in LayoutRoot but not when it's child of ScrollViewer.
I think the exception is explanatory. Like you apply storyboard on some UI element but there is no element named "transform" in your xaml to which this storyboard will be going to be applied.
so this property Storyboard.TargetName should be name of the UI element that has to be transformed.
In your case if you have to simply give your StackPanel a name say MyStackPanel and then put this name in place of transform in your storyboard code.
<StackPanel Orientation="Horizontal" Name="MyStackPanel">
<StackPanel.RenderTransform>
<TranslateTransform x:Name="transform" />
</StackPanel.RenderTransform>
...
You storyboard should be changedin this way..
<phone:PhoneApplicationPage.Resources>
<Storyboard x:Name="Scroll" RepeatBehavior="Forever" AutoReverse="True">
<DoubleAnimation From="0" To="100" Storyboard.TargetName="MyStackPanel" Storyboard.TargetProperty="X" Duration="0:0:5" />
</Storyboard>
</phone:PhoneApplicationPage.Resources>
Important :-It would be much better if you just use Blend for making a simple animation and then see how the animation code generated in the page Xaml. You will got all of your answers :)
Related
I'm trying to rotate a font icon inside a button 90° in the first click and back to 0° on the second click.
Currently I have:
<Page.Resources>
<Storyboard x:Name="RotateButton90Degrees">
<DoubleAnimation
EnableDependentAnimation="True"
Storyboard.TargetName="ShowSubTasks_ButtonRotateTransform"
Storyboard.TargetProperty="Angle"
From="0"
To="90"
Duration="350" />
</Storyboard>
</Page.Resources>
<Button
x:Name="ShowSubTasks_Button"
Background="Transparent">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<media:ControlStoryboardAction Storyboard="{StaticResource RotateButton90Degrees}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
<FontIcon
FontFamily="Segoe MDL2 Assets"
Glyph=""
RenderTransformOrigin="0.5, 0.5">
<FontIcon.RenderTransform>
<RotateTransform x:Name="ShowSubTasks_ButtonRotateTransform" />
</FontIcon.RenderTransform>
</FontIcon>
</Button>
The problem is that the app crashes when I click the button (it's not finding the ShowSubTasks_ButtonRotateTransform). The second is that I don't know how to revert the rotation effect after the first click (first click -> 90°, second click -> 0°, third click -> 90° and so on).
Any help would be appreciated.
Ok i got the problem, the thing is that im running all that code inside a DataTemplate ... So that explains why its crashing. For the fix i used what #Dishant suggested, created two storyboards and with a DataTriggerBehavior i change the angle of the rotate transform
<StackPanel.Resources>
<Storyboard x:Name="RotateButtonTo90Degrees">
<DoubleAnimation
EnableDependentAnimation="True"
Storyboard.TargetName="ShowSubTasks_ButtonRotateTransform"
Storyboard.TargetProperty="Angle"
From="0"
To="90"
Duration="0:0:0.1" />
</Storyboard>
<Storyboard x:Name="RotateButtonTo0Degrees">
<DoubleAnimation
EnableDependentAnimation="True"
Storyboard.TargetName="ShowSubTasks_ButtonRotateTransform"
Storyboard.TargetProperty="Angle"
From="90"
To="0"
Duration="0:0:0.1" />
</Storyboard>
</StackPanel.Resources>
<Button
Background="Transparent"
Visibility="{Binding HasSubTasks, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="{Binding ShowSubTasks, Mode=OneWay}" Value="True">
<media:ControlStoryboardAction Storyboard="{StaticResource RotateButtonTo90Degrees}" />
</core:DataTriggerBehavior>
<core:DataTriggerBehavior Binding="{Binding ShowSubTasks, Mode=OneWay}" Value="False">
<media:ControlStoryboardAction Storyboard="{StaticResource RotateButtonTo0Degrees}" />
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<FontIcon
FontFamily="Segoe MDL2 Assets"
Glyph=""
RenderTransformOrigin="0.5, 0.5">
<FontIcon.RenderTransform>
<RotateTransform x:Name="ShowSubTasks_ButtonRotateTransform" />
</FontIcon.RenderTransform>
</FontIcon>
</Button>
Also as #MartinZikmund suggested, i needed to change the duration from 350 to something like 0:0:0.5
In my case the app does not crash, but the icon does not rotate, because the duration is set to 350, which basically means 350 hours. If you change this value to something like 0:0:0.5, it should rotate in 0.5 seconds. To do the reverse animation, you would probably need to set the animation target programatically, but in such case you could just run the storyboard itself in the Click event handler.
If you are targeting Windows 10 15063 or higher, you can use Implicit Animations in XAML. In that case you could set up an implicit animation on the rotation of the icon and then just set the rotation property in the code-behind accordingly and implicit animation would take care of the animation itself.
I wrote a storyboard which make a ball (imgBall) running repeatedly on a process bar (imgBar) - with repeat behavior = "forever", but I don't see event which occur when single turn start or end, It only have Completed event (which occur when the whole storyboard finished)
<Grid Margin="20,0,0,0">
<Canvas Canvas.ZIndex="1" >
<Canvas.Resources>
<Storyboard x:Name="myStoryboard" Completed="myStoryboard_Completed">
<!-- Animate the center point of the ellipse. -->
<DoubleAnimation Storyboard.TargetName="imgBall"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)"
Duration="0:0:2"
From="10" To="350"
RepeatBehavior="Forever"
></DoubleAnimation>
</Storyboard>
</Canvas.Resources>
<Image Source="/Assets/Image/processball.png" x:Name="imgBall">
<Image.RenderTransform>
<CompositeTransform TranslateX="10" TranslateY="2"/>
</Image.RenderTransform>
</Image>
</Canvas>
<Image Source="/Assets/Image/imgBar.png"/>
</Grid>
</StackPanel>
You can remove RepeatBehavior="Forever" and repeat your Storyboard from code behind in Completed event Handler using .Begin() method.
I am working on a c# wpf project and I have run in to a problem relating to firing an trigger within the XAML.
What I am trying to achieve is when the drags a file into the grid, it should animate the background colour change but for some reason it keeps on throwing an exception as soon as I run the program. I am getting the following error:
'Provide value on
'System.Windows.Baml2006.TypeConverterMarkupExtension' threw an
exception.' Line number '9' and line position '14'.
Below is the XAML code
<UserControl x:Class="ReportReader.UserControls.ReportDragDropControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
<Grid AllowDrop="True" DragDrop.DragOver="Grid_DragOver"
DragDrop.DragEnter="Grid_DragEnter" DragDrop.Drop="Grid_Drop" DragDrop.DragLeave="Grid_DragLeave">
<Grid.Triggers>
<EventTrigger RoutedEvent="Grid.DragEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="#cecece" Storyboard.TargetProperty="(Grid.BackgroundColor).(SolidColorBrush.Color)" FillBehavior="Stop" Duration="0.0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<TextBlock Margin="12,12,20,12" Name="txtDragDropStatus" Text="Drag file here or use file menu to load your report" TextAlignment="Center" FontSize="30" FontWeight="Bold" TextWrapping="WrapWithOverflow" Width="835" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</UserControl>
Thanks for any help you can provide.
There are two errors in your XAML file -
BackgroundColor is not a Dependency Property, instead use Background.
0.0.1 is not a valid value for TimeSpan. It should be 0:0:1.
This will work fine -
<ColorAnimation To="#cecece"
Storyboard.TargetProperty="(Grid.Background)
.(SolidColorBrush.Color)"
FillBehavior="Stop" Duration="0:0:1" />
Also, to allow animation on background property, you should set it to some default value.
<Grid Background="White"/>
I tried with this sample and its working fine on drag enter -
<Grid AllowDrop="True" Background="White" DragDrop.DragEnter="Grid_DragEnter">
<Grid.Triggers>
<EventTrigger RoutedEvent="Grid.DragEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="#cecece"
Storyboard.TargetProperty="(Grid.Background).
(SolidColorBrush.Color)"
FillBehavior="Stop" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
/EventTrigger>
</Grid.Triggers>
<TextBlock Margin="12,12,20,12" Name="txtDragDropStatus"
Text="Drag file here or use file menu to load your report"/>
</Grid>
I'm really new to WPF so if you can point me to a tutoiral as well i will be very happy :)
here is my curreny code:
<Grid Name="Grid">
<local:Card Loaded="Card_Loaded"
x:Name="MyCard">
<local:Card.Triggers>
<EventTrigger RoutedEvent="local:Card.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MyCard"
Storyboard.TargetProperty="Opacity"
From="1.0"
To="0.0"
Duration="0:0:5"
AutoReverse="True"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</local:Card.Triggers>
</local:Card>
</Grid>
local:Card is a UserControl
Here is why i use x:Name="" and not Name="":
Because 'MS.Internal.Design.Metadata.ReflectionTypeNode' is implemented in the same assembly, you must set the x:Name attribute rather than the MS.Internal.Design.Metadata.ReflectionPropertyNode attribute.
And i can see the Card and everything but the Animation doesn't work =\
Here is the card XAML:
<UserControl.Resources>
<x:Array Type="{x:Type s:String}"
x:Key="src">
<s:String>Foo</s:String>
</x:Array>
<DataTemplate x:Key="frontTemplate">
<Grid Background="Transparent">
<Image Source="Images\Card.jpg" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="backTemplate">
<GroupBox Header="Back"
Background="White">
<StackPanel>
<RadioButton Content="This"
IsChecked="True" />
<RadioButton Content="Is" />
<RadioButton Content="The" />
<RadioButton Content="Back" />
</StackPanel>
</GroupBox>
</DataTemplate>
</UserControl.Resources>
<ScrollViewer>
<ItemsControl Width="180"
Height="250"
ItemsSource="{StaticResource src}"
ItemTemplate="{StaticResource flipItemTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
I copied your XAML exactly and ran it in a window. The only change I made was to replace the local:Card object with a TextBlock (since I didn't have a Card usercontrol). The animation ran perfectly.
So either your local:Card object has something strange that isn't allowing the animation to work or the Loaded="Card_Loaded" method in this line:
<local:Card Loaded="Card_Loaded" x:Name="MyCard">
is interfering with the event trigger:
<EventTrigger RoutedEvent="local:Card.Loaded">
Put the storyboard in either the EventTrigger.EnterActions or EventTrigger.Actions tags.
I recently dived in to some WPF animations....here's the link that got me started:
http://www.galasoft.ch/mydotnet/articles/article-2006102701.aspx
Solution:
<Grid Name="Grid">
<local:Card x:Name="MyCard" MouseEnter="MyCard_MouseEnter" />
</Grid>
<Window.Resources>
<Storyboard x:Key="sbdCardAnim">
<DoubleAnimation
Storyboard.TargetName="MyCard"
Storyboard.TargetProperty="Opacity"
From="1" To="0" Duration="0:0:5"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</Window.Resources>
C#:
private void MyCard_MouseEnter(object sender, MouseEventArgs e)
{
Storyboard sbdCardAnim = (Storyboard)FindResource("sbdCardAnim");
sbdCardAnim.Begin(this);
}
i want a silverlight listbox whose items are automatic scrollable (like a vertical marquee)
You might try using an ItemsControl setting the ItemsControl.ItemPanel to a StackPanel with a TranslateTransform applied on it. Then you can have a running Storyboard that adjusts the position of the Y coordinate of the Translate Transform.
EDIT: Example
<Border BorderBrush="Black" BorderThickness="2"
Height="100" Width="100"
HorizontalAlignment="Left" VerticalAlignment="Top" >
<Border.Clip>
<RectangleGeometry Rect="0,0,100,100" />
</Border.Clip>
<ItemsControl ItemsSource="{StaticResource Collection}">
<ItemsControl.RenderTransform>
<TranslateTransform x:Name="Transform" />
</ItemsControl.RenderTransform>
<i:Interaction.Triggers>
<i:EventTrigger>
<ei:ControlStoryboardAction
Storyboard="{StaticResource TransformMove}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ItemsControl>
</Border>
Then include this Storyboard in your control resources:
<Storyboard x:Key="TransformMove" Storyboard.TargetName="Transform" Storyboard.TargetProperty="Y">
<DoubleAnimation From="-100" To="100" Duration="0:0:10"
RepeatBehavior="Forever"/>
</Storyboard>