XAML Defined StoryBoard throws nullpointer when called in C - c#

I'm trying to animate a button so the image enlarges when the user touches it and goes back to normal when he releases It but somehow the XAML Defined StoryBoard throws a nullpointer when called in C#. My code snippets are down here, I've got no clue at all what creates this problem.
XAML:
<UserControl x:Class="Mavie_Base.GUIElements.MenuButton"
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"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="200" d:DesignWidth="140">
<UserControl.Resources>
<Storyboard x:Name="Enlarge">
<DoubleAnimation Duration="0:0:1" From="60" To="66" Storyboard.TargetProperty="Height" Storyboard.TargetName="Rectangle"/>
</Storyboard>
<Storyboard x:Name="Normalize">
<DoubleAnimation Duration="0:0:1" From="66" To="60" Storyboard.TargetProperty="Height" Storyboard.TargetName="Rectangle"/>
</Storyboard>
</UserControl.Resources>
....
</UserControl>
C#:
private void IconContainer_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
Enlarge.Begin();
}
private void IconContainer_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
Normalize.Begin();
}

+1 #thumbmunkeys
Though if it were me, it sounds like something you might want to add other stuff to later for interaction so I'd just let functionality already built in to handle that and then have room to add to it later if you want to add other stuff to its functionality. I'd also think (not positive, would have to check) if you go tinkering with the height property it may offset other artifacts layed out on the screen as it adjusts causing for a jumpy UI that wouldn't be very pleasing to the user.
Again, if it were me, I would probably just do something like this instead. First, instead of fiddling with the Height/Width properties that might push other parts of the screen around, hit the ScaleTransform.ScaleY (and ScaleX respectively, you'll want to play with the Values I'm sure to get the sizes you want.) for your size changes.
I'd also probably go ahead and make it into a "lookless" and stripped down Button for other options later and to handle my events like Pressed. Something like;
<Style x:Key="GrowOnPressedThingy" TargetType="Button">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="Container"
RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</Grid.RenderTransform>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<!-- Just left for reference -->
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Container"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0:0:0.01" Value="1.05" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Container"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0.01" Value="1.05" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused"/>
<VisualState x:Name="Unfocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="contentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
IsTabStop="False"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This way you could just do a quick... ;
<Button Content="whatever/image/path/blah.png"
Style="{StaticResource GrowOnPressedThingy}"/>
...wherever you need it, and you've got it setup to go easily add other neat UI tricks you might think of in the future. Just a shot in the dark, but maybe worth considering.
Anyway, hope this helps. Cheers

Try casting the targetproperty:
Storyboard.TargetProperty="(FrameworkElement.Height)"

Related

'Fill' property does not point to a dependencyobject in path '(0).(1)'

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.

Is Databinding or TemplateBinding supported within the VisualStateManager?

I am trying to delay an animation of a custom control based on a binding value. In the example below, I’d like the animation to start 5 seconds after the “SelectedAndHit” visual state is selected. However, it doesn’t seem possible to use template binding within the VisualStateManage.
Is TemplateBinding supported within the VisualStateManager? Is there any workaround?
<local:ButtonEx x:Name="Button01" AnimationBeginTime="00:00:05" />
public TimeSpan AnimationBeginTime
{
get { return (TimeSpan)base.GetValue(ButtonEx.AnimationBeginTimeProperty); }
set { base.SetValue(ButtonEx.AnimationBeginTimeProperty, value); }
}
public static readonly DependencyProperty AnimationBeginTimeProperty =
DependencyProperty.Register("AnimationBeginTime", typeof(TimeSpan), typeof(ButtonEx), new PropertyMetadata(TimeSpan.Zero));
<Style TargetType="local:ButtonEx">
<!-- ... -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ButtonEx">
<Grid x:Name="Container" RenderTransformOrigin="0.5, 0.5">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="SelectedAndHit">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundColorSelectedAndHit}" />
</ObjectAnimationUsingKeyFrames>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="GridScaleTransform"
Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
To="1.2" BeginTime="{TemplateBinding AnimationBeginTime}" Duration="00:00:00.300" AutoReverse="True">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseIn" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation
Storyboard.TargetName="GridScaleTransform"
Storyboard.TargetProperty="(ScaleTransform.ScaleY)"
To="1.2" BeginTime="{TemplateBinding AnimationBeginTime}" Duration="00:00:00.300" AutoReverse="True">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseIn" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RenderTransform>
<ScaleTransform x:Name="GridScaleTransform" />
</Grid.RenderTransform>
<!-- ... -->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I confirm that WinRT doesn't support Binding/TemplateBinding within a style. To workaround the issue I wrote code to manually update the BeginTime of the Storyboard. That way I had full control on when the Storyboard begins.
I would look at Interactivity. I've personally used the EventTrigger with GoToStateAction, which was enough for my purposes. From looking at MSDN it looks like you might be able to make use of TimerTrigger and GoToStateAction to create the effect you're looking for. TimerTrigger has dependency properties for setting the delay of the action to fire.

How to change the appearance of a MenuFlyout in Windows Phone?

I read mostly all of this article, but I just can't find out how I can change e.g. the entrance theme transition of the MenuFlyout, like it appears in the calender app. There is something like a horizontal turn instead of the default Animation of the MenuFlyout.
<MenuFlyout>
<MenuFlyout.MenuFlyoutPresenterStyle>
<Style...../>
</MenuFlyout.MenuFlyoutPresenterStyle>
<MenuFlyoutItem Text="Test"/>
</MenuFlyout>
C#:
MenuFlyout mf = (MenuFlyout)this.Resources["AddButtonFlyout"];
mf.Placement = FlyoutPlacementMode.Bottom;
mf.ShowAt(this.CommandBar);
The MenuFlyout has a standard Style which is set for TargetType="MenuFlyoutPresenter" and can be found in ..\Program Files (x86)\Windows Phone Kits\8.1\Include\abi\Xaml\Design\generic.xaml (I will not copy/paste here because it's quite long). This Style defines a ControlTemplate which you can modify to set how the MenuFlyout behaves when it changes to BottomPortrait VisualState.
From what I can see in the Calendar app, the MenuFlyout kind of flips when you open it. In predefined Style it first displays the top border and then draws the rest from top to bottom.
So, first of all you need to copy the whole Style to your resources. Then you need to find the BottomPortrait VisualState and clear everything from the Storyboard to be able to define your own from scratch.
I'll use a PlaneProjection class - it give that sort of a 3D effect which is what you're looking for. I added it to the CenterBorder Border element and set the default value to -90. I set it to -90 because that means it's perpendicular to the screen and the MenuFlyout is therefore not visible when first shown.
// ... rest of the code
<Border x:Name="CenterBorder" FlowDirection="LeftToRight" BorderBrush="{TemplateBinding Background}">
<Border.Projection>
<PlaneProjection RotationX="-90"/>
</Border.Projection>
// ... rest of the code
The next (and final) step is to define the new Storyboard in BottomPortrait VisualState as mentioned earlier - and it's really simple:
// ... rest of the code
<VisualState x:Name="BottomPortrait">
<Storyboard>
<DoubleAnimation Duration="0:0:0.18"
To="0"
Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)"
Storyboard.TargetName="CenterBorder" />
</Storyboard>
</VisualState>
// ... rest of the code
It just animates the Border from -90 to 0 degrees in very short period of time, which makes it go from invisible to visible with a nice flip animation, which is what you're looking for.
The Style (with irrelevant parts omitted for brevity - you should still have them!):
<Style TargetType="MenuFlyoutPresenter">
<!-- OTHER PROPERTY SETTERS -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuFlyoutPresenter">
<Border x:Name="OuterBorder" FlowDirection="LeftToRight" BorderBrush="{TemplateBinding BorderBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PlacementStates">
<VisualState x:Name="None" />
<VisualState x:Name="TopPortrait">
<!-- TOP PORTRAIT STORYBOARD -->
</VisualState>
<VisualState x:Name="BottomPortrait">
<Storyboard>
<DoubleAnimation Duration="0:0:0.18"
To="0"
Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)"
Storyboard.TargetName="CenterBorder" />
</Storyboard>
</VisualState>
<VisualState x:Name="LeftLandscape">
<!-- LEFT LANDSCAPE STORYBOARD -->
</VisualState>
<VisualState x:Name="RightLandscape">
<!-- RIGHT LANDSCAPE STORYBOARD -->
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border.RenderTransform>
<ScaleTransform x:Name="OuterScaleTransform" />
</Border.RenderTransform>
<Border x:Name="CenterBorder" FlowDirection="LeftToRight" BorderBrush="{TemplateBinding Background}">
<Border.Projection>
<PlaneProjection RotationX="-90"/>
</Border.Projection>
<StackPanel x:Name="InnerBorder" FlowDirection="{TemplateBinding FlowDirection}" Background="{TemplateBinding Background}">
<StackPanel.RenderTransform>
<ScaleTransform x:Name="InnerScaleTransform" />
</StackPanel.RenderTransform>
<ItemsPresenter x:Name="ItemsPresenter" Margin="{TemplateBinding Padding}" FlowDirection="{TemplateBinding FlowDirection}" />
</StackPanel>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
EDIT:
Showing the MenuFlyout is best done on a frame.
MenuFlyout mf = (MenuFlyout)this.Resources["AddButtonFlyout"];
mf.Placement = FlyoutPlacementMode.Bottom;
Frame fr = Window.Current.Content as Frame;
mf.ShowAt(fr);

Windows Store App not Scaling

I am developing a Windows Store app, and I hit a problem with scaling to different screen sizes - namely, 140 and 180%. Everything works perfectly on my computer, which is scaled to 100%, but when I test it on the Surface Pro and on the different simulator options that are not scaled to 100%, it starts acting up. I am pretty sure the problem is with the <VisualStateManager> but that is about as far as I can tell.
The problem only appears in the Snapped state, and what happens is in Landscape mode at 140%, the title sometimes appears and sometimes stays blank. Sometimes, clicking the title works to bring up the menu - even if it is blank, while other times nothing happens. The curious part about it is that somehow whether or not it works depends on the data loaded in the DataFrame frame, so if I change the content of those pages to the same content as a working page, it works. The shorter pages appear to have more problems, but that is the only pattern I can find.
When the screen is scaled to 140% portrait mode, none of the text is visible, but some is still clickable.
When the screen is scaled to 180%, the text is not visible, not is it clickable.
Image of title not showing:
Image with title showing:
This is my MainPage.xaml code:
<Page
x:Name="mainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:LearnOneNote"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="LearnOneNote.MainPage"
mc:Ignorable="d"
Margin="-2">
<Grid Background="White" x:Name="MainGrid">
<Grid.Resources>
<local:StringToTitleConverter x:Key="Convert" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="100" x:Name="TitleRow"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" x:Name="ItemsColumn"/>
<ColumnDefinition Width="*" x:Name="DataColumn"/>
</Grid.ColumnDefinitions>
<ListBox x:Name="Items" Grid.Column="0" Grid.RowSpan="2" ItemsSource="{Binding ItemList}" Padding="5" SelectionChanged="newSelect" Tapped="Items_Tapped"/>
<Border x:Name="Border" Grid.Column="1" Margin="10,0,10,10" BorderThickness="0,0,0,2" BorderBrush="Brown" MaxHeight="100" VerticalAlignment="Bottom"/>
<Viewbox x:Name="TitleView" Margin="10,0,10,10" VerticalAlignment="Center" Grid.Column="1" Grid.Row="0">
<TextBlock Foreground="Brown" Text="{Binding ElementName=Items, Path=SelectedValue, ConverterParameter=PrimaryView, Converter={StaticResource Convert}}" Margin="5,10,5,5"/>
</Viewbox>
<Viewbox x:Name="TitleViewSnapped" Margin="10,0,10,10" VerticalAlignment="Center" Grid.Column="1" Grid.Row="0" Visibility="Collapsed">
<TextBlock x:Name="TitleSnapped" Foreground="Brown" Text="{Binding ElementName=Items, Path=SelectedValue, ConverterParameter=Snapped, Converter={StaticResource Convert}}"
Margin="0,10,5,5" PointerEntered="Title_PointerEntered" PointerExited="Title_PointerExited" Tapped="Title_Tapped"/>
</Viewbox>
<Frame Grid.Column="1" Grid.Row="1" Margin="20,20,0,20" x:Name="DataFrame" FontSize="20" Foreground="Black" VerticalAlignment="Top" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ViewStates">
<VisualState x:Name="PrimaryView"/>
<VisualState x:Name="Snapped">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ItemsColumn" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0" Value="0"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TitleView" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TitleViewSnapped" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="ItemsSelector">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="DataColumn" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0" Value="0"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ItemsColumn" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0" Value="*"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Items" Storyboard.TargetProperty="FontSize">
<DiscreteObjectKeyFrame KeyTime="0" Value="25"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</Page>
If I delete this bit from <VisualState x:Name="Snapped">, I have no problem with my text disappearing, although the clicking problem is still there:
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Title" Storyboard.TargetProperty="Text">
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding ElementName=Items, Path=SelectedValue, ConverterParameter=Snapped, Converter={StaticResource Convert}}"/>
</ObjectAnimationUsingKeyFrames>
I searched the internet for other people having this problem and found these MSDN pages:
Scaling to Pixel Density
Resizing to Narrow Layouts
Support Multiple Screen Sizes
I have already made all of these changes to the best of my knowledge.
My simplified program is available in files here
My images are available here
I don't think you can have bindings in animations. I'd try two separate TextBlocks that bind to different values and alternate Visibility of these in visual state storyboards if different text is how you want to differentiate between views.
OK, this is absolutely crazy. I solved my problem by removing the margin of -2 on the page:
<Page
x:Name="mainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:LearnOneNote"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="LearnOneNote.MainPage"
mc:Ignorable="d"
Margin="-2">
becomes:
<Page
x:Name="mainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:LearnOneNote"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="LearnOneNote.MainPage"
mc:Ignorable="d">
Everything started working immediately in all scale sizes, although I have a thin white line around my page. Any information on why this did this and how to remove that white line is welcome.

How to Reverse WPF Storyboard animation?

I've created a WPF Storyboard animation on an image in Expression Blend 4. On hover, the image gradually blurs. Is there any way I can have the Storyboard be undone or reversed when the mouse leaves the image? I could make it trigger Storyboard.Remove() but that wouldn't actually play through the Storyboard backwards.
Is there any way I can accomplish that within Expression Blend 4?
Since you are using Blend, you should take advantage of Blend's support for the VisualStateManager. All you have to do is describe what the object looks like in its various states, like MouseOver and Normal and how long the transitions between various states are, and the visual state manager works out how to transition between states.
An image doesn't have any visual states but you can edit a Button template and make its content an image and then edit the states for the button. I've done this and cleaned up the XAML to demonstrate the technique:
<Grid>
<Grid.Resources>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Image x:Name="image" Height="100" Width="Auto" Source="http://thecybershadow.net/misc/stackoverflow.png" Margin="0,0,-25,0">
<Image.Effect>
<DropShadowEffect ShadowDepth="0"/>
</Image.Effect>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.5"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.ShadowDepth)" Storyboard.TargetName="image">
<EasingDoubleKeyFrame KeyTime="0" Value="15"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed"/>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Image>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Button Style="{StaticResource ButtonStyle1}"/>
</Grid>
Note that Blend does all this for you but understanding the XAML will help. Here's a Blend-oriented tutorial:
MORE ARTICLES ON VISUAL STATE MANAGER
Maybe the solution is on this Answer:
How to animate ListBox Items on MouseEnter and MouseLeave events using C#/WPF?

Categories

Resources