Wpf - Animate height from bottom up - wpf

I am trying to create something similar in style to Skypes notifications but am having some problems with the animation.
I would like the entire window to appear with a border at the top and bottom and then for the content in the middle to grow "pushing" the borders with it.
I have managed to create something that does almost what I want however it grows from the top down where as I would like it to push up with the bottom border stationery.
I am using the following animation on the middle section that I would like to appear
<DoubleAnimation
Storyboard.TargetName="contentGrid"
BeginTime="00:00:0.2"
Storyboard.TargetProperty="(FrameworkElement.Height)"
From="0"
Duration="0:0:0.5"/>
Any Ideas?
Thanks
Rest of the XAMl:
<Grid Name="notificationPanel">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="contentGrid" Storyboard.TargetProperty="(FrameworkElement.Height)" From="0" Duration="0:0:0.5"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Grid Grid.Row="0" Background="CornflowerBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Name="notificationTitle" Padding="5" FontSize="14" Foreground="White">
Call Manager - Incoming Call
</TextBlock>
<Path Name="closeButton" Grid.Column="1" Margin="5,10,10,0" Fill="White" Data="F1 M 2.28484e-007,1.33331L 1.33333,0L 4.00001,2.66669L 6.66667,6.10352e-005L 8,1.33331L 5.33334,4L 8,6.66669L 6.66667,8L 4,5.33331L 1.33333,8L 1.086e-007,6.66669L 2.66667,4L 2.28484e-007,1.33331 Z " />
</Grid>
<Grid Name="contentGrid" Grid.Row="1" Background="White" Height="15" VerticalAlignment="Bottom" >
</Grid>
<Rectangle Grid.Row="2" Fill="CornflowerBlue" Height="5" />
</Grid>

The behavior you are seeing is being determined by the UIElement that contains your <Grid Name="notificationPanel"> grid.
If this Grid is placed inside an element with the height set to 'Auto', it will animate from the top down, which is not what you want.
If this Grid is placed inside a container with either a fixed height, or the height set to *, and you have set the VerticalAlignment of your 'notificationPanel' Grid to 'Bottom', then you will get the correct animation behavior, with your 'contentGrid' growing up and pushing up the top border also, while the bottom border remains stationary.
It's one of those things about WPF that took me a long time to learn :) The containing element often controls the behavior and/or appearance of its child elements.

I didn't get your question exactly, but what i understood from your question is currently you able to animate contentGrid height from 0 to 15 which is bottom to top and you want to make it top to bottom as well so you can try following code
<DoubleAnimation Storyboard.TargetName="contentGrid"
Storyboard.TargetProperty="(FrameworkElement.Height)"
To="0"
Duration="0:0:0.5"/>
You can also try AutoReverse="True" if you want to animate height from 0 to 15 and back to 0.
If something else you expecting in this answer please explain you question more clearly.

Related

How do I transition the Grid.Row value of a TextBlock, based upon resizing the window in WPF?

I'm trying to gain experience at using VisualStateManager, which I haven't much expreience at, in a .NET Core WPF app. I've got a grid on the window, with 3 TextBlocks in it. When I narrow the window to 380 pixels or less, I want to move one of the TextBlocks from Grid.Row 0, to Grid.Row 1. I looked up how I might do this, but the example code I came across made use of VisualState.StateTriggers. However, when I tried to use that in the code I'm working with, Intellisense didn't recognize VisualState.StateTriggers, so I'm not sure how to proceed. And when I resize the window to more than 380 pixels I want to put that TextBlock's GridRow back to 0. I started using a DoubleAnimation, but again I don't know how trigger the change in state. I'm working with .NET Core 3.1, its a WPF app. Here's what I've got so far:
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Left">Some text in the upper left</TextBlock>
<TextBlock
x:Name="UpperRightTextBlock"
HorizontalAlignment="Right"
Text="Some text in the upper right">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="WideView">
<VisualState x:Name="GoToWideView">
<!--<Storyboard>
<DoubleAnimation
Storyboard.TargetName="GridRow"
Storyboard.TargetProperty="Grid.Row"
To="0"
Duration="0" />
</Storyboard>-->
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</TextBlock>
<TextBlock
x:Name="BottomTextBlock"
Grid.Row="2"
HorizontalAlignment="Center">
This text is in the bottom row
</TextBlock>
</Grid>

Animate width WPF left sided

I have a Gridwhich I'm able to animate the following way:
When I click on the image, I can animate the template of my button with a Storyboard to grow as much as I want as a result like this:
That would be the result more or less. The animation looks like this:
<Storyboard x:Key="ExpandPanelRight">
<DoubleAnimation
Storyboard.TargetName="ExpandablePanel"
Storyboard.TargetProperty="Width"
BeginTime="0:0:0"
From="0" To="450" Duration="0:0:0.5"></DoubleAnimation>
</Storyboard>
As you can see, no problem while growing the grid from left to right, but what I really want is the opposite: expand the Grid from right to left:
How will it be?? I can't find the answer.
All you need to do is to align your bin Image to the right edge of your ExpandablePanel. Once you have done that then the Image will stick to the right hand side as the Width of the Panel increases. your Storyboard and DoubleAnimation code can remain the same. Your code should look something like this:
<Border CornerRadius="10" Background="Blue">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="Expanding...." VerticalAlignment="Center" />
<Image Source="Images/Bin.png" VerticalAlignment="Center" HorizontalAlignment="Right" />
</Grid>
</Border>

How to make a multipaged UserControl in WPF?

I'm trying to make a user control which contains three different pages, each displaying different content. My idea was to make the following: create the user control main grid, then create another grid with the width set to three times the width of the user control or the main grid, and then create three columns in it. Then I would create a grid for each of the columns, wrapping each page content. Next, create two buttons to slide the pages, changing them through a translate transform animation.
I did it all right, but the sliding doesn't work as I expected: when the grid is translated, the content of the new page doesn't get displayed, and the other page keeps visible in the side of the user control.
The code is as follows:
.cs
private void TranslateMainGrid(bool right)
{
DoubleAnimation gridTranslateAnimation = new DoubleAnimation(); // Calculations not important
gridTranslateAnimation.From = right ? 0 - (this.SelectedPanel - 1) * 286 : 0 - (this.SelectedPanel + 1) * 286;
gridTranslateAnimation.To = 0 - this.SelectedPanel * 286;
gridTranslateAnimation.Duration
= new Duration(new TimeSpan(0, 0, 0, 0, 500));
TranslateTransform oTransform
= (TranslateTransform)PanelGrid.RenderTransform;
oTransform.BeginAnimation(TranslateTransform.XProperty,
gridTranslateAnimation);
}
.xaml
<Grid x:Name="MainGrid" Height="400" Width="286" Background="#7B9D9D9D" RenderTransformOrigin="0.5,0.5">
<Grid x:Name="PanelGrid" Height="400" Width="858" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TranslateTransform X="0"/>
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid x:Name="ChimeraGrid" Grid.Column="0">
<Grid.Background>
<ImageBrush ImageSource="/GameView;component/Resources/arcaneCreature.png"/>
</Grid.Background>
</Grid>
<Grid x:Name="CreatureGrid" Grid.Column="1">
<Grid.Background>
<ImageBrush ImageSource="/GameView;component/Resources/chimeraTest.png"/>
</Grid.Background>
<Label Content="lolololol" Height="81" VerticalAlignment="Top" HorizontalAlignment="Right" Width="164"/>
</Grid>
<Grid x:Name="EquipmentGrid" Grid.Column="2">
<Grid.Background>
<ImageBrush ImageSource="/GameView;component/Resources/tribeCreature.png"/>
</Grid.Background>
</Grid>
</Grid>
</Grid>
The code was simplified, but I guess it ilustrates the whole stuff. How can I deal with this grids? Is there any other way to do what I intended here?
Thanks
Replace your top-level Grid
<Grid x:Name="MainGrid" Width="286" ...>
by a Canvas and set the ClipToBounds property:
<Canvas Name="MainCanvas" Width="286" ClipToBounds="True">
Moreover you have to set the Height property of those Grids in the three columns that don't have any content. Setting only the Background to an ImageBrush will not affect the Grid's size. The result is that the three Grids have Width=286 (resulting from 858 divided by three columns) but the left and right Grid have Height=0, because they have no content. The middle one gets its height from the contained Label and is hence visible.
Instead of setting an ImageBrush you could also put an Image control in each column Grid. Thus the heights of the three Grids would be set automatically.
Of course ClipToBounds also works with a Grid, but it seems that the Grid won't re-render any previously invisible parts of its content when a RenderTransform is applied to that content.
When using a Canvas you may also consider to animate the Canvas.Left property instead of using a TranslateTransform.
EDIT: Here is the XAML from my test program:
<Window x:Class="SlidingGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="500" Width="400">
<Canvas Width="286" ClipToBounds="True" Margin="10">
<Grid Width="858" Name="grid" Canvas.Left="0" Height="400">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RenderTransform>
<TranslateTransform x:Name="slideTransform"/>
</Grid.RenderTransform>
<Grid Grid.Column="0">
<Grid.Background>
<ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
<Grid Grid.Column="1">
<Grid.Background>
<ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
<Grid Grid.Column="2">
<Grid.Background>
<ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Tulips.jpg" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
</Grid>
</Canvas>
</Window>
and the code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += (o, e) =>
{
//grid.BeginAnimation(
// Canvas.LeftProperty,
// new DoubleAnimation(-572, TimeSpan.FromSeconds(2)));
slideTransform.BeginAnimation(
TranslateTransform.XProperty,
new DoubleAnimation(-572, TimeSpan.FromSeconds(2)));
};
}
}

How do I allow a Silverlight popup to size to its content but prevent it from growing?

I am creating a Silverlight dialog class which is more MVVM-friendly. The ChildWindow class has some awkwardness which makes it difficult to manage from a view model.
This means I need to declare my own user interface. I have all of the traditional elements in place, including a Popup control and an overlay with 50% opacity. The open/close behavior is also working.
The problem I am having is that my control template doesn't prevent the dialog body from growing in response to the user typing into a TextBox. When the amount of characters grows beyond the default size, the entire dialog body stretches horizontally. Obviously this is not normal behavior.
What I would like to accomplish is a way for the dialog body to size itself appropriately to the content, but not expand or contract in response to child controls which require more or less space. This is how the ChildWindow control behaves, but I have examined its template and I can't determine how that works.
I think I am seeing the expansion behavior because my template is based on Grids, which allow child controls as much size as they request. I have tried several permutations of StackPanel, ScrollViewer, and other layouts with no success. Does anyone have some insight into how ChildWindow accomplishes its static, content-sized layout, or perhaps another suggestion?
Here is the template I have so far, stripped down to the bare essentials:
<Popup>
<Grid x:Name="overlay">
<Border>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
...Title...
</Grid>
<Grid Grid.Row="1">
<ContentControl Content="{TemplateBinding DialogBody}" />
</Grid>
</Grid>
</Border>
</Grid>
</Popup>
When DialogBody contains a TextBox or anything else which changes the layout size, such as hidden controls, the entire content of the Popup grows. I don't want to resort to a static width and height, because I want the dialog to automatically size to the dialog body, but only initially.
Not sure that this is wat you want..., but
wyh don't you register for Loaded event of "overlay" nad when Load will fire set the heigh and width of "overlay" ActualHeight and ActualWidth accordingly.
In this way control will get the size it want initially and wont change after that.
EDIT:
you can use this to do this in declarative way.
<Grid.Triggers>
<EventTrigger RoutedEvent="Grid.Loaded">
<BeginStoryboard>
<Storyboard x:Name ="setWidth">
<DoubleAnimation Storyboard.TargetName="overlay" Storyboard.TargetProperty="Width" From="0" To="{Binding ActualWidth, ElementName=overlay}"/>
<DoubleAnimation Storyboard.TargetName="overlay" Storyboard.TargetProperty="Height" From="0" To="{Binding ActualHeight, ElementName=overlay}"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>

Circular effect in ticker-silverlight

I am working on a silverlight ticker application, something like 5 links will be visible and they will be moving like a ticker(right to left).
I am able to parse the i/p xml file and also getting the Title and corresponding urls, those are coming properly in the page, also its moving like a ticker , but the circular effect is missing.means the continuous flow of links are not proper.
<Grid x:Name="LayoutRoot">
<StackPanel x:Name="mystackpanel" Grid.Column="1" Orientation="Vertical">
<Canvas>
<Canvas.Resources>
<Storyboard x:Name="sb">
<DoubleAnimation x:Name="da" BeginTime="00:00:05"
Storyboard.TargetName="LinkList"
Storyboard.TargetProperty="(Canvas.Left)"
From="0" To="-500" Duration="0:0:5" RepeatBehavior="Forever"/>
</Storyboard>
</Canvas.Resources>
<ListBox x:Name="LinkList"
BorderThickness="0"
Opacity="0.5"
HorizontalAlignment="Left"
>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel x:Name="panel" Orientation="Horizontal" HorizontalAlignment="Left"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<HyperlinkButton x:Name="mylink"
Foreground="Black"
FontSize="10"
FontWeight="Bold"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Tag="{Binding}"
Content="{Binding Path=Title}"
NavigateUri="{Binding Path=URi}"
IsTabStop="False"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Canvas>
</StackPanel>
</Grid>
How to get the circular effect?
Here is the the simplest approach to get the effect you need.
Set the From in the double animation to the width of the outer StackPanel. That way your URLs start from the extreme right.
Make sure the To value is the negative of at least the full width of the content to be scrolled.
Add a RectangleGeometry to your outer StackPanel that starts at 0,0 and has the width and height of your StackPanel.
Adjust the Duration to get a reasonable pixels/second rate (you want a constant speed not appearing to increase in speed as more content is present).

Resources