I am trying to create a user control similar to a stock ticker. It will slowly scroll the items to the left. So far I am unable to get something going because:
I am new to WPF/XAML and everywhere I search seems to apply to
silvelight
I am using an ItemTemplate within a ItemsControl, and cant find any
examples showing how to add a storyboard for a item within an item template.
here is my XAML:
<UserControl x:Class="WpfApplication.Ctrls.MessageTicker"
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"
mc:Ignorable="d"
xmlns:ctrls="clr-namespace:WpfApplication.Ctrls"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Background="Honeydew">
<ItemsControl ItemsSource="{Binding}" Name="_items">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="_panel">
<Grid.Triggers>
<EventTrigger RoutedEvent="Grid.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Grid.RenderTransform).(TranslateTransform.X)"
Storyboard.TargetName="_panel"
From="0"
To="360"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Word}" Grid.Column="0" Margin="0" FontWeight="Normal" FontFamily="Segoe UI Semibold"/>
<TextBlock Text="{Binding Path=Percent}" Grid.Column="1" Margin="5,0,3,0" FontFamily="Segoe UI Mono" Foreground="Blue"/>
<Polygon Points="0,10 5,0 10,10" Stroke="Black" Fill="Green" Grid.Column="2" Margin="0,3,10,0"/>
<Polygon Points="5,10 10,0 0,0" Stroke="Black" Fill="Red" Grid.Column="2" Visibility="Collapsed"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
From what I have read, I should be putting the storyboard within the template. When I add a new item to the ItemsControl, nothing happens. I need to have it start at the end of the ItemsControl and scroll to the right all the way to the beginning of the ItemsControl.
Ok so you're close, but you're missing some key things that might explain why it's not firing as you'd expect.
So your first issue lies with how you're using _panel. We'll want to actually move that to an RenderTransform on this Grid that's acting as your parent.
So instead of;
<Grid x:Name="_panel">
We'll say;
<Grid>
<Grid.RenderTransform>
<TranslateTransform x:Name="_panel">
</Grid.RenderTransform>
...
Because your TargetProperty setting in your storyboard isn't going to magically append that Transform on demand like it looks you're thinking it might (at least I've never seen it done that way I don't think).
So we have that, now let's go talk to that Transform via your Storyboard and have it talk to an actual property of your Transform thusly;
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="X"
Storyboard.TargetName="_panel">
<SplineDoubleKeyFrame KeyTime="0:0:0" Value="360" />
</DoubleAnimation>
</Storyboard>
So what we're doing is basically saying "HEY _panel, guess what? You get to animate, and before you start I want you to know you're moving 360 across your X axis"
We could add a keytime here to make this happen over more keyframes to allow it to fill in the blanks of an actual animation sequence (your ticker anime, hint hint) but for now, we're just telling that bugger to move.
Other than that, you should work. Hope this helps, cheers.
Oh and PS, you'd be surprised how much XAML can work between WPF/SL/WP, etc. etc. if you just know the fundamentals. Best of luck!
Related
I'm creating an XML Form Reader. Each of the control types are User Controls. However when the user taps somewhere on the form that isn't a focused control (i.e. TextBlock), the form jumps focus to the first focusable control in the page. (i.e. TextBox)
This scrolls the page to the top (usually), taking the user away from what they were just working on.
I have tried a lot of different things around the focus events but have hit a wall on how to solve this.
What would be the best way to handle this ? Any hints or tips would be greatly appreciated.
Thanks
EDIT (more info)
The "MASTER" page has a StackPanel
<StackPanel x:Name="pnlFormMain" ScrollViewer.BringIntoViewOnFocusChange="False"/>
For each control in the xml form, a UserControl is added to the stackpanel.
<UserControl.Resources>
<Storyboard x:Name="Show">
<DoubleAnimation Duration="0:0:0.6" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="_WidgetMaster" d:IsOptimized="True"/>
</Storyboard>
<Storyboard x:Name="Hide">
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="_WidgetMaster" d:IsOptimized="True"/>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="grdInput" ScrollViewer.BringIntoViewOnFocusChange="False">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Grid.Row="0" ScrollViewer.BringIntoViewOnFocusChange="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<!-- label -->
<TextBlock x:Name="lblLabel" Text="Label" Grid.Column="0" VerticalAlignment="Center" Margin="3,6,5,5" TextWrapping="Wrap" />
<!-- HINT -->
<Ellipse x:Name="ellHint" Height="25" Width="25" Grid.Column="1" StrokeThickness="2" Stroke="LightBlue" Margin="5,0,5,0" Tapped="Hint_Tapped" VerticalAlignment="Center">
<Ellipse.Fill>
<ImageBrush ImageSource="ms-appx:///XForms/Assets/information.png" />
</Ellipse.Fill>
</Ellipse>
</Grid>
<Frame x:Name="control" Grid.Column="1" Grid.Row="0" />
<TextBlock x:Name="lblConstraintMessage" Grid.Row="2" Grid.ColumnSpan="99" FontSize="10" VerticalAlignment="Center"
HorizontalAlignment="Right" Margin="0,0,5,0" Visibility="Collapsed" />
</Grid>
The same UserControl is used for almost all controls. And the input for that control is a second UserControl that goes into the Frame near the bottom.
(e.g.)
<Grid x:Name="grdInput">
<TextBox x:Name="txtInput" Text="" Grid.Row="0" Grid.Column="1" Margin="15,0,0,0" LostFocus="txtInput_LostFocus" KeyDown="txtInput_KeyDown" TextAlignment="Right" />
<Border x:Name="brdrValuePlaceholder" Background="Transparent" BorderThickness="0,0,0,1" BorderBrush="{ThemeResource TextControlBorderBrush}" HorizontalAlignment="Stretch"
Height="{ThemeResource TextControlThemeMinHeight}" Visibility="Collapsed">
<TextBlock x:Name="lblInput" Text="" Grid.Row="0" Grid.Column="1" Margin="0,0,5,0" Tapped="lblInput_Tapped" TextAlignment="Right" HorizontalAlignment="Stretch"/>
</Border>
</Grid>
The LostFocus event there just sets a value in the database
Other controls on the master page is a Popup and a ProgressRing
Along with a header bar.
EDIT 2
I have tried to do what I can with making the StackPanel unfocusable, and storing the previously focused control, but can get them to work as hoped.
I have put the source up on GitHub, I am new to GitHub, so if I need to do anything more, please let me know. The code is a bit older, but has the same problem. There is also a Android and iOS application in the solution, but only the UWP project has the issue.
The bounty is still alive, and will be awarded if anyone can help.
Thanks
Maybe it is focusing on the stackpanel itself?
Have dialog box popup or a textstring in the page itself to show what is always focused. That way you can see if the stacklayout is becoming focused.
Another possibility is that if you tap off, it is returning focus to the first element on the stacklayout (what it saw as tapped).
It's not trivial to recreate your exact scenario. However, there should be several possible solutions to your problem.
The first thing that comes to my mind is to intercept the Preview*keyboard/mouse events within your form.
When a KeyDown/MouseDown/Tap outside your text box is detected while it has the focus, call update the binding expression of the FocusManager, and set Handled=true to prevent the KeyDown or MouseDown event from being processed further if a non-user control is clicked. A markup extension could be helpful too.
It might be also crucial to hangle PreviewLost*Focus to detect any unwanted focus changes.
Another approach could be to mark all no-user input UI elements as Focusable=false in the XAML, e.g.
<XY Focusable="False">
...
</XY>
or disable them all together.
I have created a usercontrol that has some controls outside of view, but they will be visible as soon as animation show them. Animation is changing their offset, so they slowly appears. Now, when I put my usercontrol on some view,
those controls that I don't want to be seen are visible. I tied to use Grid, GridView, Canvas...but everytime I can see these controls.
I need 4 of my usercontrols in a row, to be resizeble. And this issue makes some usercontrols to overlap eachother.
Here is how I have show them in grid:
<Grid x:Name="gridDown" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="25*" />
</Grid.ColumnDefinitions>
<local:MyUserControl x:Name="myControl1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="0"/>
<local:MyUserControl x:Name="myControl2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="1"/>
<local:MyUserControl x:Name="myControl3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="2"/>
<local:MyUserControl x:Name="myControl4" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="3"/>
</Grid>
How to show only central part of my usercontrol? How to hide rest of the controls that I don't want to be seen? What control is the best for this?
To control what's displayed you need to tell it where to set the limits of what to show. In WPF has the helpful ClipToBounds property but unfortunately this isn't available in UWP so you need to set the 'Clip' property yourself.
So, if your page looked like this
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<local:MyControl/>
<local:MyControl/>
<local:MyControl/>
</StackPanel>
And your control XAML looked like this
<Grid Height="50" Width="100">
<Grid.Clip>
<RectangleGeometry Rect="0 0 100 50"/>
</Grid.Clip>
<Grid.Resources>
<Storyboard x:Name="ShowRedBit">
<DoubleAnimation Storyboard.TargetProperty="Rectangle.RenderTransform.(CompositeTransform.TranslateX)"
Storyboard.TargetName="RedBit"
Duration="0:0:2"
To="0"/>
</Storyboard>
</Grid.Resources>
<Button HorizontalAlignment="Center" Click="Button_Click">show red</Button>
<Rectangle Fill="Red" Height="50" Width="50" x:Name="RedBit" RenderTransformOrigin="0.5,0.5" >
<Rectangle.RenderTransform>
<CompositeTransform TranslateX="-100"/>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
You can see that I've manually set the clip property to be the same as the size of the control.
The answers to this question also show some other approaches, including a way to set it dynamically.
I am looking at the windows 8 grid project that comes with VS2012 and trying to understand it. I don't know too much about XAML so I getting quite easily lost of where binding code is happening and such.
<Page.Resources>
<!--
Collection of grouped items displayed by this page, bound to a subset
of the complete item list because items in groups cannot be virtualized
-->
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="TopItems"
d:Source="{Binding AllGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/>
</Page.Resources>
<!--
This grid acts as a root panel for the page that defines two rows:
* Row 0 contains the back button and page title
* Row 1 contains the rest of the page layout
-->
<Grid Style="{StaticResource LayoutRootStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Horizontal scrolling grid used in most view states -->
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.RowSpan="2"
Padding="116,137,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="1,0,0,6">
<Button
AutomationProperties.Name="Group Title"
Click="Header_Click"
Style="{StaticResource TextPrimaryButtonStyle}" >
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" Margin="3,-7,10,10" Style="{StaticResource GroupHeaderTextStyle}" />
<TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-7,0,10" Style="{StaticResource GroupHeaderTextStyle}"/>
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
<!-- Vertical scrolling list only used when snapped -->
<ListView
x:Name="itemListView"
AutomationProperties.AutomationId="ItemListView"
AutomationProperties.Name="Grouped Items"
Grid.Row="1"
Visibility="Collapsed"
Margin="0,-10,0,0"
Padding="10,0,0,60"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource Standard80ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="7,7,0,0">
<Button
AutomationProperties.Name="Group Title"
Click="Header_Click"
Style="{StaticResource TextPrimaryButtonStyle}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" Margin="3,-7,10,10" Style="{StaticResource GroupHeaderTextStyle}" />
<TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-7,0,10" Style="{StaticResource GroupHeaderTextStyle}"/>
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
<TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" Grid.Column="1" IsHitTestVisible="false" Style="{StaticResource PageHeaderTextStyle}"/>
</Grid>
<VisualStateManager.VisualStateGroups>
<!-- Visual states reflect the application's view state -->
<VisualStateGroup x:Name="ApplicationViewStates">
<VisualState x:Name="FullScreenLandscape"/>
<VisualState x:Name="Filled"/>
<!-- The entire page respects the narrower 100-pixel margin convention for portrait -->
<VisualState x:Name="FullScreenPortrait">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Padding">
<DiscreteObjectKeyFrame KeyTime="0" Value="96,137,10,56"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<!--
The back button and title have different styles when snapped, and the list representation is substituted
for the grid displayed in all other view states
-->
<VisualState x:Name="Snapped">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
The first area I don't understand is this
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="TopItems"
d:Source="{Binding AllGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/>
I don't get where this Source="{Binding Groups}" is actually coming from (I am not even sure how to find the code F12 does not work).
Same with the d:Source not sure 100% what is going on there as well.
The next part is in the gridview and again with the binding.
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.RowSpan="2"
Padding="116,137,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
I see that Items Source is using that groupItemsViewSource but not sure how it is parsing the data into the grid look but not sure how.
The next part I don't get is how does it figure out what layout to use. I see this in the comments
<!-- Horizontal scrolling grid used in most view states -->
<!-- Vertical scrolling list only used when snapped -->
I am sure if I look even deeper into it I will find more I don't understand but maybe when I understand this stuff I will understand more(especially once I understand this binding stuff)
I don't get where this Source="{Binding Groups}" is actually coming
from (I am not even sure how to find the code F12 does not work).
Note at the top of the page:
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
which sets the context for the binding on that page to the DefaultViewModel property of the page. In the code behind for the page you'll see
this.DefaultViewModel["Groups"] = sampleDataGroups;
where sampleDataGroups is a list (IEnumerable) of groups (type SampleDataGroup) returned from a method call. Now you also have,
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="TopItems"
d:Source="{Binding AllGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/>
and here "Groups" refers to the key that indexes the DefaultViewModel, so it's going to use that subset of the DefaultViewModel. Furthermore, each item in the CollectionViewSource itself contains a collection, and those collections are surfaced to the binding engine at whatever property ItemsPath specifies, namely, TopItems.
Now from the GridView binding:
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.RowSpan="2"
Padding="116,137,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
you noted that the data is coming from that specific instance of a CollectionViewSource named groupedItemsViewSource (which in this case is equivalent to this.DefaultViewModel["Groups"]). If you look at the header template a bit later, you'll see:
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" Margin="3,-7,10,10" Style="{StaticResource GroupHeaderTextStyle}" />
...
The Title binding refers to the property of an element in the ItemsSource collection, so this.DefaultViewModel["Groups"][i].Title
ItemTemplate="{StaticResource Standard250x250ItemTemplate}" in the GridView binding governs how the inner collection items are displayed. You'll have to crack that style open (in Common/StandardStyles.xaml) to see that it references properties of a SampleDataItem, essentially leading to this.DefaultViewModel["Groups"][i].TopItems[j].
The d: prefix refers to design time data (well, a namespace that includes classes that manage it); it's what allows you do see the data in the designer without running your application. So at design time the data you are seeing actually comes from SampleDataSource.AllGroups.
As for the comments about scrolling, that gets into the VisualStateManager, each state essentially being a different take on the UI; states transition via a bit of code you can find inside of LayoutAwarePage.cs look for GotoState.
I don't get where this Source="{Binding Groups}" is actually coming from
Bindings target the DataContext of the element -- to find it, you typically scan up the XAML to find where DataContext was last set. So in this case, it must either set on the Page element somehow. (The DataContext can also be set from code-behind, although I'd be surprised if that were the case in the VS sample project.)
Same with the d:Source not sure 100% what is going on there as well.
The d prefix is referring to design-time data. Check for the SampleDataSource, that's where you'll find the design-time instance of AllGroups.
not sure how it is parsing the data into the grid
The Grid auto-generates its columns based on the properties of its row data type.
Hi I am developing an animation in which flip animation is required as shown in http://www.avatar-app.com/dev/2012/01/24/ios-flip-transform/ (Similar to weatherflow app in wp7). Now I am successful in achieving this by making use of two border one above the other and animating one border using planeprojection. And here is my code
<Grid x:Name="ContentPanel" Background="Wheat" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation Storyboard.TargetName="planeProjection" Storyboard.TargetProperty="RotationX" From="0" To="90" Duration="0:0:5" />
</Storyboard>
</Grid.Resources>
<Border Background="AliceBlue" Grid.Row="0" ManipulationStarted="Border_ManipulationStarted">
<Border .Projection>
<PlaneProjection x:Name="planeProjection" CenterOfRotationY="1"/>
</Border .Projection>
</Border>
<Border Background="Aqua" Grid.Row="1">
</Border>
</Grid>
The problem is, here I am using two controls(Border), but I want to use animation on only one control i.e dividing the animation so that it applies to half part of the control(only one border)?
Guys help me.
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");
}