Binding to ObservableCollection with transition - c#

I have ItemsControl which I bind to ObservableCollection
On my view model I just insert object and it pops onto UI
I want to show transition. For example, I want this item to fade in so user registers this change visually, let's say it happens in 1 second.
What should I look for? How it's done in WPF?
EDIT:
I think I need some kind of animation but what I'm looking for is something simple without coding. Plain XAML implementation, is anything built-in? I tried TranslateTransform and other choices but it doesn't do anything.
<ItemsControl ItemsSource="{Binding Source={StaticResource TrucksSource}}">
<ItemsControl.RenderTransform>
<TranslateTransform />
</ItemsControl.RenderTransform>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TruckId}" Background="Aqua"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

For fade-in, you can use an EventTrigger on the Loaded event for the ContentPresenters
<ItemsControl ItemsSource="{Binding Source={StaticResource TrucksSource}}">
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Style.Triggers>
<EventTrigger RoutedEvent="Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="Opacity">
<DoubleAnimation From="0.0"
To="1.0"
Duration="00:00:01"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TruckId}" Background="Aqua"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Read this: http://msdn.microsoft.com/en-us/library/ms750596.aspx
You need Animating Transformations (last chapter) and change Opacity value from 1.0 to 0.0

Related

Rotating a visible set of elements in WPF

This is more for advertising deals to potential customers so there is no human interaction component to this.
Right now I just have the elements bound to an ItemsControl and a storyboard animation loops through. Unfortunately I want to show 4 items at a time, pause on them for 10 seconds, then show the next 4. I could have 5 coupons, I could have 30, so I can't enter anything in statically except that I know my visible width (they will be rotating horizontally) is 1920px.
My current implementation, which displays 1 to 4 then 5 to 8 and loops back to "1" is:
<ItemsControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" ItemsSource="{Binding Path=VisibleDigitalCoupons}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Storyboard x:Key="RotateDigitalCoupons" BeginTime="0:0:0" Duration="0:0:10" RepeatBehavior="Forever" Completed="RotateDigitalCouponsCompleted">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)" Storyboard.TargetName="digitalCouponView">
<EasingDoubleKeyFrame KeyTime="0:0:5" Value="0"></EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:10" Value="-1920">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"></CubicEase>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</DataTemplate.Resources>
<views:DigitalCouponView x:Name="digitalCouponView" Margin="40,40,20,20" Height="240" Width="420" RenderTransformOrigin="0.5,0.5" >
<views:DigitalCouponView.RenderTransform>
<TransformGroup>
<TranslateTransform/>
</TransformGroup>
</views:DigitalCouponView.RenderTransform>
</views:DigitalCouponView>
<DataTemplate.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard x:Name="RotateDigitalCoupons_BeginStoryboard" Storyboard="{StaticResource RotateDigitalCoupons}"/>
</EventTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Attempts to use the Completed event to fire off a refresh of the "visible coupons" and reuse the animation have met with failure because the animation is on repeatbehavior forever. However, even with that off, I don't get completed event firing, so that's a dead end AFAIK.
Anyone have any ideas or dealt with this before? Is my process flawed somehow?
Create a Dispatch Timer which contains a state machine which will execute the logic depending on the current state and handle the data driven components of what will be displayed. Within the timer turn on and off the animations as required.
You will need to make the animations more generic of course, but you have the framework which can be leveraged by the timer.

Changing style for individual item in ListBox programmatically

I saw some examples for changing colors and brushes for selected item in a ListBox
I was wondering if there is a way to change visual properties of an item in a list box based on events in our code
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Name="spSceneThumb" Width="110">
<Border BorderThickness="1" Background="#FFfcfcfc" BorderBrush="#aaaaff" >
<StackPanel></StackPanel>
</Border>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
Let say I want to change border color of 5th item based on some event
I tried IValueConverter But changes to property wont effect border color
You can declare a custom RoutedEvent that you could listen to with an EventTrigger. You can find out how to declare a custom RoutedEvent in the How to: Create a Custom Routed Event page on MSDN. Once created, you can reference your custom event using the class name before the event name and not forgetting the XAML Namespace Prefix that you define for the namespace where it was declared. Something like this:
RoutedEvent="YourNamespacePrefix:YourClassName.YourEventName"
However, changing discrete values like Brushes is not so simple using an EventTrigger. You'll have to use a Storyboard with a DiscreteObjectKeyFrame element. You could try something like this:
<DataTemplate x:Key="Something">
<StackPanel Name="spSceneThumb" Width="110">
<Border Name="Border" BorderThickness="1" Background="#FFFCFCFC">
<StackPanel>
...
</StackPanel>
<Border.Resources>
<SolidColorBrush x:Key="EventBrush" Color="Red" />
</Border.Resources>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="BorderBrush" Value="#FFAAAAFF" />
<Style.Triggers>
<EventTrigger RoutedEvent="Prefix:YourClassName.YourEventName">
<EventTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="Border"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0:0:0"
Value="{StaticResource EventBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.EnterActions>
</EventTrigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</StackPanel>
</DataTemplate>

animating an observablecollection move operation in the UI wpf?

I have a wrappanel bound to an observablecolelction.
Is there a way to animate the movement of items in the UI when the collection is changed in the code behind? Kind of like the fluid movement of windows tiles style metro apps?
Any design ideas of how to go about this will be appreciated.
Right now, all I can think of is animating the layout chaging event?
Thanks
I've needed such thing in the past and -as I remember- I ended using a slightly modified version of the sample provided here:
https://learn.microsoft.com/en-us/archive/blogs/devdave/layout-transitions-an-animatable-wrappanel
This sample is somewhat advanced and supports animating the items when any modification is made to the collection (adding items, deleting items, resizing the panel)
On the other hand if what you need is a simple animation at the item level only (e.g. when an item is appearing/disappearing) it's much simpler you can build an ItemTemplate with a control that has an EventTrigger for the relevant event. This example will animate the item when added:
XAML:
<StackPanel>
<ItemsControl x:Name="itemsControl" Height="300">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="80" Height="80" Fill="Red" Margin="4" Opacity="0">
<Rectangle.RenderTransform>
<TranslateTransform Y="20" />
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="00:00:00.6" />
<DoubleAnimation Storyboard.TargetProperty="(RenderTransform).Y" To="0" Duration="00:00:00.4" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Width="60" Height="40" Content="Add Item" Click="Button_Click" />
</StackPanel>
Code behind:
ObservableCollection<string> items = new ObservableCollection<string>();
public MainWindow()
{
InitializeComponent();
itemsControl.ItemsSource = items;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
items.Add("New Item");
}

WPF UserControl Animation wont work..?

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);
}

want a silverlight listbox with vertical marquee like effect

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>

Categories