I design an application for Windows RT. I used VisualStateManager for snapped in a user control. but when my application snapped the user control is not changed. where is the problem?
<Grid Width="500" Height="40" Margin="15" x:Name="questionRoot" Background="DarkSeaGreen">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" >
<TextBlock x:Name="OrginalWord" FontSize="32" Text="{Binding Question.OrginalWord}"></TextBlock>
</StackPanel>
<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"/>
<!--
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="OrginalWord" Storyboard.TargetProperty="FontSize">
<DiscreteObjectKeyFrame KeyTime="0" Value="88"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
Are you calling the VisualStateManager.GoToState method in codebehind? You need to detect when the application transitions from Full/Fill to Snap mode, and call this method then.
You'll find the MSDN documentation for this function here.
You generally recognize this transition when the size of your Page parent control or application Window changes. This SO question (look at the answer by Jowen) gives you a code snippet on how to do this by listening to the Window's size changed event.
I had a similar issue I found a solution that helped me and may be someone find it useful if the usercontrol is hosted in layoutawarepage
<my:usercontrole Loaded="StartLayoutUpdates" Unloaded="StopLayoutUpdates" />
otherwise you will have to de the follow (example can be found in the layout aware page)
•make event handler on sizechanged
•in the event handler check the viewstate with ApplicationView.Value
•move to that state with VisualStateManager.GoToState
Related
I have a control template (which is the header component of a DevExpress NavBarGroup - in order to change the expand/collapse icon DevExpress requires to override the whole control template) with a button inside, which also has its own control template, which then contains a content control pointing to another control template with paths inside. Kinda like this in pseudo-Xaml:
<NavBarGroupHeader>
<ExplorerBarExpandButton>
<Path>
<SolidColorBrush/>
</Path>
</ExplorerBarExpandButton>
</NavBarGroupHeader>
Now, there are various things happening. The outer most template of the NavBarGroupHeader contains the problematic animation logic: As soon as the header gets hovered the Path's fill color is supposed to change. There are actually two buttons inside depending on the state of the NavBarGroupHeader using the same logic and looks, which is why I outsourced it into a template. The NavBarGroupHeader can be used with an ExplorerBarView or a NavPaneView, which then activates either of the buttons inside (the ExplorerBarExpandButton is used in this case and the NavPaneExpandButton gets ignored - but it's still there and viable).
<ControlTemplate TargetType="{x:Type dxn:NavBarGroupHeader}>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinition>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Common">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<!-- these two lines throw the exception -->
<ColorAnimation Storyboard.Target="{Binding ElementName=ArrowTop}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Duration="0" To="#201F35"/>
<ColorAnimation Storyboard.Target="{Binding ElementName=ArrowBottom}" Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" Duration="0" To="#201F35"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroup>
<!-- This shows a text within the header -->
<dxn:ImageAndTextContentPresenter/>
<dxn:ExplorerBarExpandButton x:Name="ExplorerBarExpandButton"
Grid.Column="1"
Template="{StaticResource GroupBoxExpandButtonTemplate}"/>
<dxn:NavPaneExpandButton x:Name="NavPaneExpandButton"
Grid.Column="1"
Template="{StaticResource GroupBoxExpandButtonTemplate}"/>
</Grid>
</ControlTemplate>
The ExplorerBarExpandButton contains two icons, looking the same, but one is flipped upside down with a LayoutTransform, which is why I outsorced the path into its own template. It also contains the logic of showing and hiding either of the buttons depending on whether the NavBarGroup is expanded or collapsed, which changes if you click the header (this is predetermined by DevExpress and works fine).
<ControlTemplate x:Key="GroupBoxExpandButtonTemplate">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
</VisualStateGroup>
<VisualStateGroup x:Name="ExpandStates">
<VisualState x:Name="Expanded"/>
<VisualState x:Name="Collapsed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphClose" Storyboard.TargetProperty="(Control.Visibility)" dxcn:ValueSetter.Visibility="Collapsed"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphOpen" Storyboard.TargetProperty="(Control.Visibility)" dxcn:ValueSetter.Visibility="Visible"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="GlyphClose"
Template="{StaticResource CollapseExpandIconTemplate}"/>
<ContentControl x:Name="GlyphOpen"
Template="{StaticResource CollapseExpandIconTemplate}">
<ContentControl.LayoutTransform>
<RotateTransform Angle="180"/>
</ContentControl.LayoutTransform>
</ContentControl>
</Grid>
</ControlTemplate>
The path is actually a StackPanel with two Paths inside (two arrows pointing in the same direction). Therefore I actually wanted to use a DynamicResource of a color but after hours of trying and searching I stumbled across this post explaining that it is not possible to access a resource inside the targeted element from within a storyboard. So, now I'm left with this:
<ControlTemplate x:Key="CollapseExpandIconTemplate">
<StackPanel>
<Path x:Name="ArrowTop" Stretch="Uniform" Fill="#80838F" Data="M 0,50 25,50 50,30 75,50 100,50 100,40 50,0 0,40 Z"/>
<Path x:Name="ArrowBottom" Stretch="Uniform" Fill="#80838F" Data="M 0,50 25,50 50,30 75,50 100,50 100,40 50,0 0,40 Z"/>
</StackPanel>
</ControlTemplate>
In multiple other posts (actually in everyone concerning this error) I've read that the declaration of a SolidColorBrush in the path is missing but adding it doesn't change anything. I still get the same error with this:
</Path ...>
<Path.Fill>
<SolidColorBrush Color="#80838F"/>
</Path.Fill>
</Path>
I also tried using dynamic resources everywhere but it showed the same exception. I tried using DoubleAnimation for the different color parts but that throws another exception (with and without brackets around the R):
Cannot resolve all property references in the property path '(0).(1).(R)'. Verify that applicable objects support the properties.
I tried to change the path because I wasn't sure whether it was actually correct but nothing worked.
Now I'm out of ideas. How can I get this storyboard to work?
EDIT:
I've tried another thing, reducing the Xaml to the simplest basics, eliminating all duplicate elements and merging all the templates together without using any resources, changing background color from the outermost element and then step by step to the innermost until I've reached the path's template, then moving the templates back into resources.
This is the Xaml outcome:
<ControlTemplate TargetType="{x:Type dxn:NavBarGroupHeader}>
<Grid x:Name="HeaderRoot">
<Grid.Background>
<SolidColorBrush Color="White"/>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinition>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Common">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Storyboard.Target="{Binding ElementName=HeaderRoot}" Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)" Duration="0" To="#201F35"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroup>
<!-- This shows a text within the header -->
<dxn:ImageAndTextContentPresenter/>
<dxn:ExplorerBarExpandButton x:Name="ExplorerBarExpandButton"
Grid.Column="1">
<dxn:ExplorerBarExpandButton.Template>
<ControlTemplate x:Key="GroupBoxExpandButtonTemplate">
<Grid x:Name="ExpandButtonRoot">
<Grid.Background>
<SolidColorBrush Color="White"/>
</Grid.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
</VisualStateGroup>
<VisualStateGroup x:Name="ExpandStates">
<VisualState x:Name="Expanded"/>
<VisualState x:Name="Collapsed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphClose" Storyboard.TargetProperty="(Control.Visibility)" dxcn:ValueSetter.Visibility="Collapsed"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphOpen" Storyboard.TargetProperty="(Control.Visibility)" dxcn:ValueSetter.Visibility="Visible"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="GlyphClose">
<ContentControl.Template>
<ControlTemplate>
<StackPanel x:Name="PathRoot">
<Path x:Name="ArrowBottom" Stretch="Uniform" Fill="#80838F" Data="M 0,50 25,50 50,30 75,50 100,50 100,40 50,0 0,40 Z"/>
</StackPanel>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
</Grid>
</ControlTemplate>
</dxn:ExplorerBarExpandButton.Template>
</dxn:ExplorerBarExpandButton>
</Grid>
</ControlTemplate>
In this case there is no exception thrown and the first part worked fine. The whole header background changes when I hover over it. Then I've changed the line to:
<ColorAnimation Storyboard.Target="{Binding ElementName=ExpandButtonRoot}" Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)" Duration="0" To="#201F35"/>
And oddly enough, still the whole header background gets changed upon hovering over it instead of just the button's background. I don't know what's going on here.
In a Windows Phone 8 app, I would like to use the animation / transition /effect used into the Windows Phone Store app when an item is selected.
Here the explanation of the animation / transition :
open the Official Windows Phone Store app
do a research
in the list of results click on an app
watch the behaviour of the title of the app (it is going on the bottom right to reappear on the page with an animation too).
I am pretty sure that I have seen this effect on several other apps. So my question could be stupid, but is there a method or something into the SDK to do this effect / animation / transition or should I do "manually" ?
Thank you in advance for your tips about the subject !
I had searched for this as well some times back but could not find any template that I need to apply in order to get the same result.
At the end, I was creating my own animations to get a similar effect.
I have a Button control which is used for a selection within my list. For the button template, I applied my own style that contains the following defintion for Visual State changes:
You can create button templates and style templates in Blend.
<Style x:Key="LongListSelectorButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Border.RenderTransform).(TranslateTransform.Y)"
Storyboard.TargetName="ButtonBackground"
From="0"
To="-6"
Duration="00:00:0.04"/>
<DoubleAnimation Storyboard.TargetProperty="(Border.RenderTransform).(TranslateTransform.X)"
Storyboard.TargetName="ButtonBackground"
From="0"
To="2"
Duration="00:00:0.04"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
This animation will move the button a bit to the top right from its current position. You can change the animation to any other direction.
Hey Guys Please Help To Sort out My Problem , i have made an app and i have to upload it on windows store but the problem is that it does not support snapped view. I want that it should not work in snapped view, when the app enters in snapped view it just display a message " Switch To Full Screen ". Please tell me how to code for that and where to code in XAML or XAML.cs. Thanks in Advance.
Add a Basic Page and replace XAML with this:
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="App1.OopsPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:common="using:App1.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<!-- Full screen content. -->
<Grid x:Name="FullScreenGrid">
<TextBlock>Here is your content.</TextBlock>
</Grid>
<!-- Snapped view content. -->
<Grid x:Name="SnappedViewGrid" Visibility="Collapsed">
<TextBlock>Please go back to full screen :(</TextBlock>
</Grid>
<VisualStateManager.VisualStateGroups>
<!-- Visual states reflect the application's view state -->
<VisualStateGroup x:Name="ApplicationViewStates">
<VisualState x:Name="FullScreenLandscape"/>
<VisualState x:Name="Filled"/>
<VisualState x:Name="FullScreenPortrait" />
<!-- The back button and title have different styles when snapped -->
<VisualState x:Name="Snapped">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FullScreenGrid" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SnappedViewGrid" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</common:LayoutAwarePage>
Make sure to replace App1 with your app namespace and you must have LayoutAwarePage.cs in your Common folder.
One of the possible solutions
Create a new page which you would want to use for Snap
Listen to the event which is raised when the user snaps the app.
Navigate to that page which has "Switch to Full Screen"
Listen to the event which is raised when the user unsnaps
Go back to the original page
To achieve this,
In your App.xaml.cs in the OnLaunched event write this
Window.Current.SizeChanged += Current_SizeChanged;
Now for the event handler
void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
{
ApplicationViewState viewState = ApplicationView.Value;
if (viewState == ApplicationViewState.Snapped)
{
//Navigate to the new common snap page
}
else{
//Write the code to check if the previous state was snapped and then navigate back
}
}
I looked on the internet but I can find this nowhere : I would like to disable the TimeHint popup that shows the current time when entering focus on a TimeUpDown control. Something like : <12:42AM>
There is no TimeHintEnabled property, nor any kind of member that seems to control this. There is a TimeHintContent property, but it is readonly and seems empty at first.
My code is really simple :
<Grid x:Name="LayoutRoot" Background="Transparent">
<toolkit:TimeUpDown Name="timeUpDown1"
Background="White"
Height="22"
MinWidth="55"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</Grid>
Maybe playing with the Template can do the trick, but I don't know how to do it...
Alright, thanks to Blend I found what I was looking for.
The Template can be easily modified by Blend, this part of the template is needed inside the xaml to hide the TimeHintPopup :
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="TimeHintStates">
<VisualState x:Name="TimeHintOpenedUp">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetProperty="Visibility"
Storyboard.TargetName="TimeHintVisualElement">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
And your TimeUpDown should refer to this template :
<toolkit:TimeUpDown Name="timeUpDown1" Background="White" Height="22" MinWidth="55" HorizontalAlignment="Left" VerticalAlignment="Top" Style="{StaticResource TimeUpDownStyle1}" />
i've been trying to deal with the following problem:
When creating a custom animations for different visual states in Expression Blend 3, which change size/opacity of multiple elements on the grid, it creates the visual state groups in the grid itself rather than in control style and defines it as CustomVisualStateManager.
<Grid x:Name="LayoutRoot" Background="White" Height="500" HorizontalAlignment="Left" VerticalAlignment="Top" Width="500">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MyVisualStateGroup">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="00:00:00.3000000">
<VisualTransition.GeneratedEasingFunction>
<CircleEase EasingMode="EaseIn"/>
</VisualTransition.GeneratedEasingFunction>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="State1"/>
<VisualState x:Name="State2">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="myBox" Storyboard.TargetProperty="(FrameworkElement.Height)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="360"/>
<!-- omitting other storyboard animations here for clarity -->
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<VisualStateManager.CustomVisualStateManager>
<ic:ExtendedVisualStateManager/>
</VisualStateManager.CustomVisualStateManager>
<!-- omitting other grid elements here for clarity -->
</Grid>
It's ok with me, but problem is, i can't switch states, in code-behind when i try
VisualStateManager.GoToState(this, "State1", true);
nothing happens, because the control itself doesn't have these visualstates defined, as shown by
VisualStateManager.GetVisualStateGroups(this);
If i try
VisualStateManager.GetVisualStateGroups(LayoutRoot);
it shows exactly what i need. But i cannot pass LayoutRoot to VisualStateManager because it needs an argument of Control type, which Grid isn't.
My question is - how can i access/ change states of this CustomVisualStateManager in code-behind?
The CustomVisualStateManager is just there when you enable FluidLayout. Unless you have layout morphing involved in your project (i.e. you are trying to use states to animate smoothly from one layout to another), you can switch it off. The presence of the custom VSM should not make any difference in the usage of VSM.
The visual state markup always is inside the top level container, so that is perfectly normal. BTW, this might be just a typo in your sample, but the code you show actually tries to set a state that has nothing in it, so that might not be the desired result.
Otherwise, calling VisualStateManager.GoToState on the UserControl should work. Here is an example I just made that works:
This is a simple Silverlight example app, with a main page and a user control that I added to the main page. The main page is really simple:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SLStateTest"
x:Class="SLStateTest.MainPage"
Width="640" Height="480">
<Grid x:Name="LayoutRoot" Background="White">
<local:UserControl1 x:Name="TestControl" Height="100" HorizontalAlignment="Left" Margin="24,32,0,0" VerticalAlignment="Top" Width="100"/>
<Button Height="40" HorizontalAlignment="Left" Margin="192,32,0,0" VerticalAlignment="Top" Width="104" Content="State 1" Click="OnClick"/>
<Button Height="40" HorizontalAlignment="Left" Margin="192,76,0,0" VerticalAlignment="Top" Width="104" Content="State 2" Click="OnClickState2"/>
</Grid></UserControl>
There is an instance of my user control, and two buttons. We'll look at what the buttons do in a second. First let's look at the UserControl (UserControl1):
<UserControl
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
x:Class="SLStateTest.UserControl1"
d:DesignWidth="280" d:DesignHeight="264">
<Grid x:Name="LayoutRoot" Background="#FF6FFE22">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Test" ic:ExtendedVisualStateManager.UseFluidLayout="True">
<VisualState x:Name="State1">
<Storyboard>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="00:00:00" Value="#FF003AFF"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="State2">
<Storyboard>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="00:00:00" Value="#FFFF0202"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<VisualStateManager.CustomVisualStateManager>
<ic:ExtendedVisualStateManager/>
</VisualStateManager.CustomVisualStateManager>
</Grid></UserControl>
As you can see, there are two visual states defined in one visual state group that just set a color on the layout root of the user control.
The two buttons on the main page are wired up to event handlers that look as follows:
private void OnClick(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
VisualStateManager.GoToState(TestControl, "State1", true);
}
private void OnClickState2(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
TestControl.SetState();
}
The first one just calls VisualStateManager.GoToState on the UserControl on the page. The second one calls a function iside of the user control that does the same thing. I just used both methods to show that both options are available - you can call VSM.GoToState from the outside or the inside of a UC. The SetState() method of the user control looks as follows:
public void SetState()
{
VisualStateManager.GoToState(this, "State2", true);
}
When you run the app, the user control will first show up in its base state , which is green. When you press the State 1 button it goes to State1, which sets the UC to blue by calling VSM.GoToState() from the outside. When you press the State 2 button, it switches to red, by calling VSM from the inside.
From the snippets you posted, I can't see what is going wrong, short of the one issue that I mentioned at the beginning. However, my little sample might help you to see what is different in your case.
Hope that helps...