I have a behaviour set up with the following code (This is just a snippet):
public class StarBehaviour : Behavior<View>
{
TapGestureRecognizer tapRecognizer;
protected override void OnAttachedTo(View view)
{
tapRecognizer = new TapGestureRecognizer();
tapRecognizer.Tapped += OnTapRecognizerTapped;
view.GestureRecognizers.Add(tapRecognizer);
}
protected override void OnDetachingFrom(View view)
{
view.GestureRecognizers.Remove(tapRecognizer);
tapRecognizer.Tapped -= OnTapRecognizerTapped;
}
void OnTapRecognizerTapped(object sender, EventArgs args)
{
//HACK: PropertyChange does not fire, if the value is not changed :-(
IsStarred = false;
IsStarred = true;
}
I have created a horizontal stack layout which stores each StarBehaviour inside it's own grid. The problem is when I test this on my device, the tap isn't recognized. I have a feeling it might have to do with the view but when I put background colours on my views, it seems to be relatively alright. Here is the xaml where the StarBehaviour is implemented:
<?xml version="1.0" encoding="utf-8" ?> <TabbedPage BackgroundColor="#8BC739" x:Name="MainTabbedPage" xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SalApp;"
x:Class="SalApp.pages.RecipePage">
<!--Pages can be added as references or inline-->
<ContentPage x:Name="AboutContentPage" Title="About" BackgroundColor="LightGray">
<ScrollView>
<StackLayout Orientation="Vertical" x:Name="AboutStack">
<BoxView x:Name ="imageBoxView" Color="DarkOrange" HorizontalOptions="FillAndExpand" BindingContext="{x:Reference imageBoxView}"
HeightRequest="{Binding Width}" />
<Grid x:Name="textAndRatingGrid" Margin="16,4,0,0" HeightRequest="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Label BindingContext="{x:Reference MainTabbedPage}" Text="{Binding Title}" Grid.Column="0"/>
<StackLayout Margin="32,0,4,0" Grid.Column="1" Orientation="Horizontal" HorizontalOptions="Fill">
<Grid BackgroundColor="DarkBlue">
<Grid.Behaviors>
<local:StarBehaviour x:Name="starOne" GroupName="myStar"/>
</Grid.Behaviors>
<Image Aspect="AspectFill" x:Name="starBlankOne" Source="stars/star_empty.png"/>
<Image Aspect="AspectFill" x:Name="starSelectedOne" Source="stars/star_full.png" IsVisible="{Binding Source={x:Reference starOne}, Path=IsStarred}"/>
</Grid>
<Grid>
<Grid.Behaviors>
<local:StarBehaviour x:Name="starTwo" GroupName="myStar"/>
</Grid.Behaviors>
<Image x:Name="starBlankTwo" Source="stars/star_empty.png"/>
<Image x:Name="starSelectedTwo" Source="stars/star_full.png" IsVisible="{Binding Source={x:Reference starTwo}, Path=IsStarred}"/>
</Grid>
<Grid>
<Grid.Behaviors>
<local:StarBehaviour x:Name="starThree" GroupName="myStar"/>
</Grid.Behaviors>
<Image x:Name="starBlankThree" Source="stars/star_empty.png"/>
<Image x:Name="starSelectedThree" Source="stars/star_full.png" IsVisible="{Binding Source={x:Reference starThree}, Path=IsStarred}"/>
</Grid>
<Grid>
<Grid.Behaviors>
<local:StarBehaviour x:Name="starFour" GroupName="myStar"/>
</Grid.Behaviors>
<Image x:Name="starBlankFour" Source="stars/star_empty.png"/>
<Image x:Name="starSelectedFour" Source="stars/star_full.png" IsVisible="{Binding Source={x:Reference starFour}, Path=IsStarred}"/>
</Grid>
<Grid>
<Grid.Behaviors>
<local:StarBehaviour x:Name="starFive" GroupName="myStar"/>
</Grid.Behaviors>
<Image x:Name="starBlankFive" Source="stars/star_empty.png"/>
<Image x:Name="starSelectedFive" Source="stars/star_full.png" IsVisible="{Binding Source={x:Reference starFive}, Path=IsStarred}"/>
</Grid>
</StackLayout>
</Grid>
<StackLayout Margin ="16,4" Orientation="Vertical">
<Label FontAttributes="Bold" Text="Description"/>
<Label HorizontalOptions="Fill" Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam non felis vitae ligula pretium congue. Integer mollis, mauris id pretium vulputate, lacus nibh pulvinar eros, euismod eleifend elit felis non ipsum. Morbi at metus quis quam pellentesque tempus ac pellentesque orci. Quisque rhoncus vulputate fringilla. Suspendisse erat arcu, pulvinar ut tincidunt non, euismod in elit. In rhoncus nibh massa, vel blandit dolor sollicitudin id. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur sollicitudin rhoncus quam quis sagittis. Fusce pharetra pretium finibus. Aliquam iaculis eget nisi laoreet vehicula. Donec odio ligula, iaculis id mollis nec, ultricies eu magna. Suspendisse molestie, erat ac gravida vulputate, neque elit ultricies leo, ut tristique mauris est eget dolor."/>
</StackLayout>
</StackLayout>
</ScrollView>
</ContentPage>
<ContentPage Title="Recipe" BackgroundColor="LightGray"/>
<ContentPage Title="Ingredients" BackgroundColor="LightGray"/>
</TabbedPage>
Any ideas where this could all be going wrong?
UPDATE: I have an idea that it has to do with the binding on the xaml. It might be that the way I set up the binding means that it's not binding to an actual view. It would appear possible due to me building the content page within a tabbed page. Although I am a beginner at bindings in Xamarin so I can't pick this apart myself.
According to your snippet you have shared. You are trying to listen the tap action for each Grid inside the StackLayout. The placement part of Grid inside the StackLayout has nothing wrong. The only thing is you have put Image inside the Grid. So there is a view which is placed above the Grid. The first priority for the touch will go for Image View. Try to set InputTransparent property of the ImageView to true. So that touch can be passed to the Grid, TapGesture callback will get fired.
Related
I'm trying to implement drop shadows on a StackPanel or in any UIElement using Win2D APIs, but it seems as if the shadow is rendering on top of the elmment and not behind where it make sense for a shadow to be.
This is my XAML:
<Page
x:Class="ShadowsDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:ShadowsDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid
Background="LightBlue">
<StackPanel
x:Name="RootHolder"
Width="400"
Height="524"
Margin="8"
Background="White"
Orientation="Vertical">
<Image Width="400" Height="200" Source="Assets/LockScreenLogo.scale-200.png" />
<StackPanel Orientation="Vertical">
<TextBlock Margin="20,20,0,0" TextWrapping="Wrap">
<Underline>
<Run
FontSize="28"
Foreground="#333366"
Text="Some title text" />
</Underline>
</TextBlock>
<TextBlock
Margin="20"
FontSize="16"
Foreground="Black"
Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
</Grid>
</Page>
And my code behind:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
var rootHolder = RootHolder;
var visualHost = ElementCompositionPreview.GetElementVisual(rootHolder);
var compositor = visualHost.Compositor;
var dropShadow = compositor.CreateDropShadow();
dropShadow.Offset = new Vector3(14, 16, 48);
dropShadow.BlurRadius = 24.0f;
dropShadow.Color = Color.FromArgb(128, 0, 0, 0);
var spriteVisual = compositor.CreateSpriteVisual();
spriteVisual.Size = new Vector2((float) rootHolder.Width, (float) rootHolder.Height);
spriteVisual.Shadow = dropShadow;
ElementCompositionPreview.SetElementChildVisual(rootHolder, spriteVisual);
}
}
An the resulting application looks like this:
With the shadow on top of the StackPanel instead of behind.
I have found an answer. It turns out order of rendering is very important in XAML.
I got the answer taking a look at windows-toolkit's DropShadowPanel
DropShadowPanel.xaml: https://github.com/windows-toolkit/WindowsCommunityToolkit/blob/master/Microsoft.Toolkit.Uwp.UI.Controls/DropShadowPanel/DropShadowPanel.xaml
DropShadowPanel.cs: https://github.com/windows-toolkit/WindowsCommunityToolkit/blob/master/Microsoft.Toolkit.Uwp.UI.Controls/DropShadowPanel/DropShadowPanel.cs
As you can see they are using a stand alone Border element with same Width and Height properties as in this case the ContentPresenter, in our case the StackPanel.
Our new code should be like this:
XAML:
<Page
x:Class="ShadowsDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:ShadowsDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid Background="LightBlue">
<Border
x:Name="RootHolder"
Width="400"
Height="524"/>
<StackPanel
x:Name="Sp"
Width="400"
Height="524"
Margin="8"
Background="White"
Orientation="Vertical">
<Image
Width="400"
Height="200"
Source="Assets/LockScreenLogo.scale-200.png" />
<StackPanel Orientation="Vertical">
<TextBlock Margin="20,20,0,0" TextWrapping="Wrap">
<Underline>
<Run
FontSize="28"
Foreground="#333366"
Text="Some title text" />
</Underline>
</TextBlock>
<TextBlock
Margin="20"
FontSize="16"
Foreground="Black"
Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
</Grid>
</Page>
Code behind:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
var rootHolder = RootHolder;//var rootHolder = (StackPanel) GetTemplateChild("RootHolder");
var visualHost = ElementCompositionPreview.GetElementVisual(rootHolder);
var compositor = visualHost.Compositor;
var dropShadow = compositor.CreateDropShadow();
dropShadow.Offset = new Vector3(14, 16, 48);
dropShadow.BlurRadius = 24.0f;
dropShadow.Color = Color.FromArgb(128, 0, 0, 0);
var spriteVisual = compositor.CreateSpriteVisual();
spriteVisual.Size = new Vector2((float) Sp.Width, (float) Sp.Height);
spriteVisual.Shadow = dropShadow;
ElementCompositionPreview.SetElementChildVisual(rootHolder, spriteVisual);
}
}
Of course this is demo code, should be trivial to bind Width and Height properties of the Border and the StackPanel (or any other UIElement) on a templated control or user control.
The final result looks like this:
I am trying to put a label inside stacklayout... The number of lines can change depending on data... But when text is more label is going out of view, its not expanding..
<StackLayout Orientation="Vertical"
BackgroundColor="White"
VerticalOptions="FillAndExpand"
Spacing="0">
<StackLayout Orientation="Vertical" BackgroundColor="Silver"
HeightRequest="45">
<AbsoluteLayout BackgroundColor="White"
HorizontalOptions="FillAndExpand"
HeightRequest="44"
Margin="0.5"
VerticalOptions="StartAndExpand"
>
<Label Text="Objective"
Margin="15,0,0,0"
AbsoluteLayout.LayoutBounds="0,0.5,-1,-1"
AbsoluteLayout.LayoutFlags="PositionProportional"
VerticalTextAlignment="Center"
FontFamily="Roboto#300" FontSize="16" FontAttributes="None" TextColor="#FF888888" />
<Button HeightRequest="32" Margin="0,0,15,0"
WidthRequest="32"
Padding="0"
x:Name="ObjectiveButton"
Clicked="Objective_Button_Handle_Clicked"
BackgroundColor="Transparent"
AbsoluteLayout.LayoutBounds="1,0.5,-1,-1"
AbsoluteLayout.LayoutFlags="PositionProportional"
Image="collapseIcon.png"/>
</AbsoluteLayout>
</StackLayout>
<StackLayout Orientation="Vertical"
BackgroundColor="White"
x:Name="ObjectiveStackLayout"
VerticalOptions="CenterAndExpand"
IsVisible="true" >
<Label Text="Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua.
Ut enim ad minim veniam,
quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea
commodo consequat."
FontFamily="Roboto#400"
FontSize="14"
VerticalTextAlignment="Center"
Margin="15,10,0,0"
MaxLines="0"
LineBreakMode="WordWrap"
FontAttributes="None"
TextColor="#FF858585" />
</StackLayout>
</StackLayout>
So Finally I solved this using Grid... Instead of taking root view as StackLayout, I took it as Grid. If we set Auto property for row height.. Label size is getting determined on the basis of its content.
What you are asking is the default behavior of a label inside a stacklayout, providing you let it.
I don't get what you are trying to do with MaxLines, here you are asking 0 line of text to show in your label, nothing should be displayed at all.
You just need to get rid of the MaxLines property, so the label can adjust depending on it's content by itself.
Either that, or I didn't get what you are trying to do.
I want to realize something like
|Image (40% Width)|Text(60% Width)|
that adapts to small screens like
|Image (100%)|
|Text(100%|
I've got the following solution with AdaptiveTrigger and an Grid.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="NarrowView">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Image.(Grid.ColumnSpan)" Value="2" />
<Setter Target="Text.(Grid.Row)" Value="1" />
<Setter Target="Text.(Grid.Column)" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="WideView">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="860" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Image.(Grid.ColumnSpan)" Value="1" />
<Setter Target="Text.(Grid.Row)" Value="0" />
<Setter Target="Text.(Grid.Column)" Value="1" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image x:Name="Image" Source="../Image.jpg" />
<TextBlock x:Name="Text" Grid.Column="1" TextWrapping="WrapWholeWords" Text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum." />
<Border Grid.Row="2" Grid.ColumnSpan="2" Background="Blue">
<TextBlock Text="Other Content" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</Grid>
My question: Is there a similar solution with the new Realtive Panel provided by Windows 10 UWP Apps?
Let's apply my thoughts about x:Null. That's what I think you mean about how to solve this. Apart there is a weird behavior of the Image using RelativePanel but I added a MaxHeight that can be replaced with the ActualHeight Binding of the Text Control if you need:
<RelativePanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="NarrowView">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Text.(RelativePanel.Below)" Value="Image" />
<Setter Target="Content.(RelativePanel.Below)" Value="Text" />
<Setter Target="Text.(RelativePanel.RightOf)" Value="{x:Null}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="WideView">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="860" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Text.(RelativePanel.Below)" Value="{x:Null}" />
<Setter Target="Text.(RelativePanel.RightOf)" Value="Image" />
<Setter Target="Content.(RelativePanel.Below)" Value="Image" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Image x:Name="Image" Source="ms-appx:///Assets/StoreLogo.png" MaxWidth="200" />
<TextBlock x:Name="Text" RelativePanel.Below="Image" TextWrapping="WrapWholeWords" Text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum." />
<Border x:Name="Content" Background="Blue" RelativePanel.Below="Text" >
<TextBlock Text="Other Content" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</RelativePanel>
The trick is setting things to {x:Null} it gives a weird warning but it works, I will also update my codeproject article with that.
I hope is the answer you were looking for.
UPDATE: The RelativeSizes:
1.- I create custom attached properties to be able to set relative size to a container:
public class RelativeSize : DependencyObject
{
private static List<FrameworkElement> elements = new List<FrameworkElement>();
private static FrameworkElement Container = null;
private static bool containerready = false;
public static void SetContainer(UIElement element, FrameworkElement value)
{
element.SetValue(ContainerProperty, value);
}
public static FrameworkElement GetContainer(UIElement element)
{
return (FrameworkElement)element.GetValue(ContainerProperty);
}
public static readonly DependencyProperty ContainerProperty =
DependencyProperty.RegisterAttached("Container", typeof(FrameworkElement), typeof(RelativeSize), new PropertyMetadata(null,ContainerChanged));
private static void ContainerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Container = (e.NewValue as FrameworkElement);
Container.SizeChanged += (sc, ec) =>
{
foreach (var element in elements)
{
var rWidth = element.GetValue(RelativeSize.WidthProperty);
if (rWidth != null)
{
element.Width = (double)rWidth * Container.ActualWidth;
}
}
};
containerready = true;
}
public static void SetWidth(UIElement element, double value)
{
element.SetValue(WidthProperty, value);
}
public static double GetWidth(UIElement element)
{
return (double)element.GetValue(WidthProperty);
}
public static readonly DependencyProperty WidthProperty =
DependencyProperty.RegisterAttached("Width", typeof(double), typeof(RelativeSize), new PropertyMetadata(0.0, WidthChanged));
private static async void WidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
while (!containerready)
await Task.Delay(60);
var fe = d as FrameworkElement;
if(fe!=null)
{
if (!elements.Contains(fe))
elements.Add(fe);
fe.Width = (double)e.NewValue * Container.ActualWidth;
}
}
}
2.- With that you can set:
xmlns:p="using:Controls.Views.Properties"
...
<Image x:Name="Image" p:RelativeSize.Container="{Binding ElementName=Root}" p:RelativeSize.Width="0.4" Source="ms-appx:///Assets/StoreLogo.png" />
<TextBlock x:Name="Text" RelativePanel.Below="Image" p:RelativeSize.Width="0.6" HorizontalAlignment="Left" TextWrapping="WrapWholeWords" Text="Lorem ipsum ..." />
UPDATE2 : The custom attached properties
XAML:
<VisualStateGroup x:Name="VisualStateGroup" CurrentStateChanged="VisualStateGroup_CurrentStateChanged">
Code:
private void VisualStateGroup_CurrentStateChanged(object sender, VisualStateChangedEventArgs e)
{
foreach (var sbase in e.NewState.Setters)
{
var setter = sbase as Setter;
var spath = setter.Target.Path.Path;
var element = setter.Target.Target as FrameworkElement;
if (spath.Contains(nameof(RelativeSize)))
{
string property = spath.Split('.').Last().TrimEnd(')');
var prop = typeof(RelativeSize).GetMethod($"Set{property}");
prop.Invoke(null, new object[] { element, setter.Value });
}
}
}
It is a solution for this custom attached property and you can adapt with more custom attached properties, using reflection in the namespace and get all and find by name, but for this is enough.
I am having issues with WinRt's ScrollViewer. Consider this minimal sample:
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<TextBlock Width="50" TextWrapping="Wrap">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
</TextBlock>
</ScrollViewer>
Zooming in just a little will cut off the text at the top. You can't actually scroll that part into view anymore. Changing the HorizontalScrollBarVisibility to Visible also doesn't work.
Am I missing something or is this truly a bug?
EDIT: Can at least someone confirm this?
The problem is you're not specifying the Height of the TextBlock. I agree -- it shouldn't work this way but it does at the moment. There are workarounds. For example:
Modify TextBlock tag as follows:
<TextBlock TextWrapping="Wrap" Width="50" VerticalAlignment="Top">
You can add a grid around the TextBlock and set the background color of the scrollview and grid to see whats going on:
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Background="Red">
<Grid Width="50" Background="Green" VerticalAlignment="Top">
<TextBlock TextWrapping="Wrap" Width="50">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
</TextBlock>
</Grid>
</ScrollViewer>
Is there some trick to make the Page.AppBars in WinRT squeeze/move the content of the page rather than going over the top of the content?
You can, but you would need to write some code to do it.
My version using visual states:
<Page.BottomAppBar>
<AppBar
x:Name="bottomAppBar"
Opened="OnBottomAppBarOpened"
Closed="OnBottomAppBarClosed">
<StackPanel
Orientation="Horizontal">
<Button
Style="{StaticResource PlayAppBarButtonStyle}" />
</StackPanel>
</AppBar>
</Page.BottomAppBar>
<Grid
Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup
x:Name="AppBarPushStates">
<VisualState
x:Name="AppBarClosed">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="pushedContentTransform"
Storyboard.TargetProperty="Y"
To="0"
Duration="0:0:0.2">
<DoubleAnimation.EasingFunction>
<CubicEase
EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</VisualState>
<VisualState
x:Name="AppBarOpened">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="pushedContentTransform"
Storyboard.TargetProperty="Y"
To="-88"
Duration="0:0:0.2">
<DoubleAnimation.EasingFunction>
<CubicEase
EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderBrush="Orange"
BorderThickness="5">
<Border.RenderTransform>
<TranslateTransform
x:Name="pushedContentTransform" />
</Border.RenderTransform>
<TextBox
TextWrapping="Wrap"
Foreground="Brown"
FontSize="48"
Text="Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna. Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci. Aenean nec lorem. In porttitor. Donec laoreet nonummy augue. Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc. Mauris eget neque at sem venenatis eleifend. Ut nonummy. Fusce aliquet pede non pede. Suspendisse dapibus lorem pellentesque magna. Integer nulla. Donec blandit feugiat ligula. Donec hendrerit, felis et imperdiet euismod, purus ipsum pretium metus, in lacinia nulla nisl eget sapien. Donec ut est in lectus consequat consequat." />
</Border>
</Grid>
Code behind:
private void OnBottomAppBarClosed(object sender, object e)
{
VisualStateManager.GoToState(this, "AppBarClosed", true);
}
private void OnBottomAppBarOpened(object sender, object e)
{
VisualStateManager.GoToState(this, "AppBarOpened", true);
}