Resolution is strange on second animation via template - c#

In my Universal Windows 10 app, I have an animation that shrinks a custom control whose looks is applied via a template. It works as expected the first time it is run. The second time it is run, the start of the animation is rendered in a horrible resolution, apparently tainted by the previous run:
First time is on the left; second time on the right.
If, instead of using a custom control with a template, I hardcode everything in XAML, the problem doesn't occur.
If I grow rather than shrink the target, the problem doesn't occur.
Let me start with the non-templated version, which is shorter and easier to read than the templated version:
<Page
x:Class="TestApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="AnimationStates">
<VisualState x:Name="Show">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="transform"
Storyboard.TargetProperty="ScaleX"
To="0.1"
BeginTime="0:00:2"
Duration="0:00:1">
</DoubleAnimation>
<DoubleAnimation
Storyboard.TargetName="transform"
Storyboard.TargetProperty="ScaleY"
To="0.1"
BeginTime="0:00:2"
Duration="0:00:1">
</DoubleAnimation>
</Storyboard>
</VisualState>
<VisualState x:Name="Hide" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Top"
Margin="16"
FontSize="122"
Text="Q">
<TextBlock.RenderTransform>
<ScaleTransform x:Name="transform" />
</TextBlock.RenderTransform>
</TextBlock>
<Button
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Margin="16"
Content="Animate!"
Click="OnAnimateClicked" />
</Grid>
</Page>
The code-behind is as follows:
public sealed partial class MainPage
{
public MainPage()
{
InitializeComponent();
}
private void OnAnimateClicked(object sender, RoutedEventArgs e)
{
VisualStateManager.GoToState(this, "Hide", useTransitions: false);
VisualStateManager.GoToState(this, "Show", useTransitions: true);
}
}
This works fine every time. But. Instead of applying the ScaleTransform to the TextBlock's RenderTransform directly, I have a custom control with a template applied. For illustration purposes we can use a custom control that is little more than a placeholder:
public sealed class CustomControl : Control
{
}
Then change the XAML to replace the TextBlock with a CustomControl, applying a template to the CustomControl:
<Page
x:Class="TestApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestApp">
<Grid>
<Grid.Resources>
<Style TargetType="local:CustomControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CustomControl">
<Grid>
<TextBlock Text="Q" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="AnimationStates">
<VisualState x:Name="Show">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="transform"
Storyboard.TargetProperty="ScaleX"
To="0.1"
BeginTime="0:00:2"
Duration="0:00:1">
</DoubleAnimation>
<DoubleAnimation
Storyboard.TargetName="transform"
Storyboard.TargetProperty="ScaleY"
To="0.1"
BeginTime="0:00:2"
Duration="0:00:1">
</DoubleAnimation>
</Storyboard>
</VisualState>
<VisualState x:Name="Hide" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<local:CustomControl
HorizontalAlignment="Center"
VerticalAlignment="Top"
Margin="16"
FontSize="122">
<local:CustomControl.RenderTransform>
<ScaleTransform x:Name="transform" />
</local:CustomControl.RenderTransform>
</local:CustomControl>
<Button
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Margin="16"
Content="Animate!"
Click="OnAnimateClicked"/>
</Grid>
</Page>
The first time I click the Animate button, this works exactly like the first version. The second and subsequent times, the initial animation rendering uses the really coarse resolution shown on the right:
The coarseness seems to be proportional to the shrinkage factor. Is this a bug of some sort (a failed optimization?), or is my understanding of templates flawed?

Related

Which layout elements should I use to implement a submenu with an animation transition

I'am very new to this WinRT and XAML stuff and not sure how to achieve this goal. For my page layout I have basically 2 rows. The first row is representing my (static) basic menu with some buttons and pictures (about 130 height). The rest of the screen should be used to display content. Like this:
screen layout
now when a user clicks on a main menu button the submenu "filter settings" should be move down with an animation. The main content is also responding to this event and moving accordingly ("filter settings" should not overlay the main content).
My current idea to define this layout is using a grid with 3 rows and 2 frames placed inside it. When no filter is activated, I use rowspan for my main content to span over the whole area. When a click event is recognized, I change the rownum of the frame which hold the main content (ModuleContentFrame) to 2 and its rowspan to 1. Then I'am loading the filter page to frame ModuleFadeInFrame.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="130"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<Frame
x:Name="ModuleFadeInFrame"
Grid.Row="1"/>
<Frame
x:Name="ModuleContentFrame"
Grid.Row="1"
Grid.RowSpan="2"/>
</Grid>
My question is: is this layout definition with a grid and frames inside it a suitable solution to solve this problem and how can I achieve a "moving" animation when displaying a sub-menu. I tried this with an Storyboard but there the main content is just "jumping" to row 2
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ModuleContentFrame"
Storyboard.TargetProperty="(Grid.Row)">
<DiscreteObjectKeyFrame KeyTime="1" Value="2" />
</ObjectAnimationUsingKeyFrames>
You can't really animate Grid row/col/etc... changes. Also any animation that'll result in a layout change is a dependent animation - and has bad performance. What I'd do is something like this:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity" xmlns:Core="using:Microsoft.Xaml.Interactions.Core"
x:Class="App1.MainPage"
mc:Ignorable="d">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="MenuState">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.3">
<VisualTransition.GeneratedEasingFunction>
<ExponentialEase EasingMode="EaseInOut"/>
</VisualTransition.GeneratedEasingFunction>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="ClosedState"/>
<VisualState x:Name="OpenState">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="grid" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid Margin="0,50,0,0" Background="Black">
<TextBlock>
Long text blablabla
</TextBlock>
</Grid>
<Grid x:Name="grid" Margin="0,50,0,0" Height="50" VerticalAlignment="Top" Background="#77ffff00">
<Grid.RenderTransform>
<CompositeTransform TranslateY="-50"/>
</Grid.RenderTransform>
<Button Content="Close" >
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:GoToStateAction StateName="ClosedState"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
</Grid>
<Grid Margin="0,0,0,0" Height="50" VerticalAlignment="Top" Background="Red">
<Button Content="Open" >
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:GoToStateAction StateName="OpenState"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
</Grid>
</Grid>
</Grid>
</Page>
This way there's no layout change, as your submenu is going to end up on top of the content.
if you're really insisting on the 'not obscuring content' way
You could just have your submenu before your content with a Height="0", and animate the height of the element with a DoubleAnimation. If you do this, you'll have to set EnableDependentAnimation to true.
More info: https://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.media.animation.pointanimation.enabledependentanimation.aspx
Thank you Tamás, you helped me a lot getting my solution. I'am doing this now as follows:
This code goes into the edit:UserControl for each submenu. On the main page I then only have to handle my Button click events and call the appropriate Animation. Next Step is getting familiar with Blend as you suggested :-)
I marked your post as answer because it was the most helpful in finding my solution
<Grid x:Name="maingrid" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
<Grid.RenderTransform>
<CompositeTransform TranslateY="-360"/>
</Grid.RenderTransform>
<Grid.Resources>
<Storyboard x:Name="myStoryboardOpen">
<DoubleAnimation Duration="0:0:0.3" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="maingrid"
d:IsOptimized="True"/>
</Storyboard>
<Storyboard x:Name="myStoryboardClose">
<DoubleAnimation Duration="0:0:0.3" To="-360" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
Storyboard.TargetName="maingrid"
d:IsOptimized="True"/>
</Storyboard>
</Grid.Resources>

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 do I call an MvxCommand/ICommand when selecting an item from a Grid?

I am enjoying the N+1DaysOfMVVMCross but I am stuck on Day 5 (Sort of a day 2 and day 5 combo)...
I used day 2 to develop a grid view UI and wanted to use the day 5 info to add a Command that will open a secondary view when an item is selected from the grid. The Command code in the ViewModel is never executed (though it does execute from a button).
I think the issue is more related to WPF/XAML but thought I would reference MVVMCross as this is where I hit the road block.
Thanks for any help/tips/direction
How about some source code...
From the view model, sorry for the list initialization I'm slowly working through this.
using Cirrious.MvvmCross.ViewModels;
using System.Collections.Generic;
using TeleBacteriology.Core.Services;
namespace TeleBacteriology.Core.ViewModels
{
public class WorklistViewModel : MvxViewModel
{
public WorklistViewModel(IWorklistItemService service)
{
var newList = new List<WorklistItem>();
WorklistItem newWorklistItem = service.CreateNewWorklistItem("201401250001", "http://placekitten.com/301/301");
newList.Add(newWorklistItem);
newWorklistItem = service.CreateNewWorklistItem("201401250002", "http://placekitten.com/302/302");
newList.Add(newWorklistItem);
newWorklistItem = service.CreateNewWorklistItem("201401250003", "http://placekitten.com/303/303");
newList.Add(newWorklistItem);
newWorklistItem = service.CreateNewWorklistItem("201401250004", "http://placekitten.com/304/304");
newList.Add(newWorklistItem);
newWorklistItem = service.CreateNewWorklistItem("201401250005", "http://placekitten.com/305/305");
newList.Add(newWorklistItem);
newWorklistItem = service.CreateNewWorklistItem("201401250006", "http://placekitten.com/306/306");
newList.Add(newWorklistItem);
newWorklistItem = service.CreateNewWorklistItem("201401250007", "http://placekitten.com/307/307");
newList.Add(newWorklistItem);
newWorklistItem = service.CreateNewWorklistItem("201401250008", "http://placekitten.com/308/308");
newList.Add(newWorklistItem);
newWorklistItem = service.CreateNewWorklistItem("201401250009", "http://placekitten.com/309/309");
newList.Add(newWorklistItem);
newWorklistItem = service.CreateNewWorklistItem("201401250010", "http://placekitten.com/310/310");
newList.Add(newWorklistItem);
Worklist = newList;
}
private List<WorklistItem> _worklist;
public List<WorklistItem> Worklist
{
get { return _worklist; }
set { _worklist = value; RaisePropertyChanged(() => Worklist); }
}
private MvxCommand _detailsCommand;
public System.Windows.Input.ICommand DetailsCommand
{
get
{
_detailsCommand = _detailsCommand ?? new MvxCommand(DoDetailsCommand);
return _detailsCommand;
}
}
private void DoDetailsCommand()
{
ShowViewModel<PlateDetailsViewModel>();
}
}
}
The XAML for the view:
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="TeleBacteriology.Store.Views.WorklistView"
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:TeleBacteriology.Store.Views"
xmlns:common="using:TeleBacteriology.Store.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<!-- Collection of items displayed by this page -->
<CollectionViewSource
x:Name="itemsViewSource"
Source="{Binding Worklist}"/>
<DataTemplate x:Key="Worklist250x250ItemTemplate">
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding ImageUrl}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding AccessionNum}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding ImageUrl}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate x:Key="Worklist80ItemTemplate">
<Grid Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}" Width="60" Height="60">
<Image Source="{Binding ImageUrl}" Stretch="UniformToFill"/>
</Border>
<StackPanel Grid.Column="1" Margin="10,0,0,0">
<TextBlock Text="{Binding AccessionNum}" Style="{StaticResource ItemTextStyle}" MaxHeight="40"/>
<TextBlock Text="{Binding ImageUrl}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
</StackPanel>
</Grid>
</DataTemplate>
<!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
<x:String x:Key="AppName">My Application</x:String>
</Page.Resources>
<!--
This grid acts as a root panel for the page that defines two rows:
* Row 0 contains the back button and page title
* Row 1 contains the rest of the page layout
-->
<Grid Style="{StaticResource LayoutRootStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Horizontal scrolling grid used in most view states -->
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemsGridView"
AutomationProperties.Name="Items"
TabIndex="1"
Grid.RowSpan="2"
Padding="116,136,116,46"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
ItemTemplate="{StaticResource Worklist250x250ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"
SelectedItem="{Binding DetailsCommand}"/>
<!-- Vertical scrolling list only used when snapped -->
<ListView
x:Name="itemListView"
AutomationProperties.AutomationId="ItemsListView"
AutomationProperties.Name="Items"
TabIndex="1"
Grid.Row="1"
Visibility="Collapsed"
Margin="0,-10,0,0"
Padding="10,0,0,60"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
SelectedItem="{Binding DetailsCommand}"
ItemTemplate="{StaticResource Worklist80ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"/>
<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
<TextBlock x:Name="pageTitle" Grid.Column="1" Text="{StaticResource AppName}" IsHitTestVisible="false" Style="{StaticResource PageHeaderTextStyle}"/>
</Grid>
<Grid Grid.Row="2">
<Button Content="Go Details" Command="{Binding DetailsCommand}" />
</Grid>
<VisualStateManager.VisualStateGroups>
<!-- Visual states reflect the application's view state -->
<VisualStateGroup x:Name="ApplicationViewStates">
<VisualState x:Name="FullScreenLandscape"/>
<VisualState x:Name="Filled"/>
<!-- The entire page respects the narrower 100-pixel margin convention for portrait -->
<VisualState x:Name="FullScreenPortrait">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Padding">
<DiscreteObjectKeyFrame KeyTime="0" Value="96,136,86,56"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<!--
The back button and title have different styles when snapped, and the list representation is substituted
for the grid displayed in all other view states
-->
<VisualState x:Name="Snapped">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</common:LayoutAwarePage>
I can post for the second view but I don't think that's necessary. Again, if I place a button in the view and set the Command binding to DetailsCommand, the second view pops up just fine. Can't get it to work with item selection on the grid.
From looking at your code, it seems you misunderstood the SelectedItem property of the ListView. It will be populated with one of your WorkListItem objects when the selection changes.
The ListView does not have a command property like the Button does, so you need to handle the SelectionChanged event of the ListView and invoke the Command on your Viewmodel manually.
You can do this in code-behind or take a look at one of the EventToCommand helpers to do it directly in xaml.

Graphical flicker/error in animation when using scrollviewer in XAML

I'm building a windows 8 store app using Visual Studio 2013 express and am coding in Xaml/c#.
When I scroll horizontally or just hold my finger on the screen my animation leaks. By leaks I mean flickering triangles appear randomly outside of the grid performing the animation.
Ive tried various settings in the scrollviewer without any luck. when I remove the scrollviewer the animation performs as expected so it appears the problem lies with the scrollviewer perhaps redrawing the elements on the page.
Below is a test app that shows the problem
MainPage.xaml
<Page.Resources>
<Storyboard x:Name="Storyboard1" AutoReverse="True" RepeatBehavior="Forever">
<DoubleAnimation Duration="0:0:0.8" To="0" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="Border" d:IsOptimized="True"/>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="Border1">
<EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="-90"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.6" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="Border2">
<EasingDoubleKeyFrame KeyTime="0:0:1.6" Value="-90"/>
<EasingDoubleKeyFrame KeyTime="0:0:2.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="Border3">
<EasingDoubleKeyFrame KeyTime="0:0:2.5" Value="90"/>
<EasingDoubleKeyFrame KeyTime="0:0:3.3" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
<ScrollViewer x:Name="MainScroll" ScrollViewer.ZoomMode="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.VerticalScrollMode="Disabled">
<StackPanel Orientation="Horizontal">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Width="500" Height="500">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid Grid.RowSpan="2" Grid.ColumnSpan="2" Background="Red"/>
<Border x:Name="Border" Background="Purple" >
<Border.Projection>
<PlaneProjection RotationY="90"/>
</Border.Projection>
</Border>
<Border x:Name="Border1" Background="Purple" Grid.Column="1" >
<Border.Projection>
<PlaneProjection RotationY="-90"/>
</Border.Projection>
</Border>
<Border x:Name="Border3" Background="Purple" Grid.Row="1" >
<Border.Projection>
<PlaneProjection RotationY="90"/>
</Border.Projection>
</Border>
<Border x:Name="Border2" Background="Purple" Grid.Row="1" Grid.Column="1" >
<Border.Projection>
<PlaneProjection RotationX="-90"/>
</Border.Projection>
</Border>
</Grid>
<Grid Width="1000" Background="Blue" Height="300" Margin="50"/>
</StackPanel>
</ScrollViewer>
MainPage.xaml.cs
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
Loaded += (s, args) =>
{
this.Storyboard1.Begin();
};
}
}
Thanks in advance
I've seen that before when writing OpenGL code on Android. It turns out I had a bug in my code. OpenGL gives all these nasty bugs when you make mistakes, because it is a giant state machine. Sorry, I can't be of more help. But it sounds like you are doing something wrong somewhere (I was). Could you try commenting things out until the problem no longer occurs? Maybe narrowing it down will help.

How to add controls dynamic in xaml apps for windows 8

I am making a grid application, and in ItemsDetaiPage.xaml
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="App6.ItemDetailPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
IsTabStop="false"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App6"
xmlns:data="using:App6.Data"
xmlns:common="using:App6.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<!-- Collection of items displayed by this page -->
<CollectionViewSource
x:Name="itemsViewSource"
Source="{Binding Items}"
d:Source="{Binding AllGroups[0].Items, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/>
</Page.Resources>
<!--
This grid acts as a root panel for the page that defines two rows:
* Row 0 contains the back button and page title
* Row 1 contains the rest of the page layout
-->
<Grid
Style="{StaticResource LayoutRootStyle}"
DataContext="{Binding Group}"
d:DataContext="{Binding AllGroups[0], Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
<TextBlock x:Name="pageTitle" Text="{Binding Title}" Style="{StaticResource PageHeaderTextStyle}" Grid.Column="1"/>
</Grid>
<!--
The remainder of the page is one large FlipView that displays details for
one item at a time, allowing the user to flip through all items in the chosen
group
-->
<FlipView
x:Name="flipView"
AutomationProperties.AutomationId="ItemsFlipView"
AutomationProperties.Name="Item Details"
TabIndex="1"
Grid.Row="1"
Margin="0,-3,0,0"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}">
<FlipView.ItemTemplate>
<DataTemplate>
<!--
UserControl chosen as the templated item because it supports visual state management
Loaded/unloaded events explicitly subscribe to view state updates from the page
-->
<UserControl Loaded="StartLayoutUpdates" Unloaded="StopLayoutUpdates">
<ScrollViewer x:Name="scrollViewer" Style="{StaticResource HorizontalScrollViewerStyle}" Grid.Row="1">
<!-- Content is allowed to flow across as many columns as needed -->
<Grid Margin="120,0,20,20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="800"></ColumnDefinition>
<ColumnDefinition Width="40"></ColumnDefinition>
<ColumnDefinition Width="400"></ColumnDefinition>
<ColumnDefinition Width="40"></ColumnDefinition>
<ColumnDefinition Width="200"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" Grid.Column="0">
<TextBlock FontSize="26.667" FontWeight="Light" Text="{Binding Title}" TextWrapping="Wrap"/>
<TextBlock FontSize="26.667" FontWeight="Light" Text="{Binding Date}" TextWrapping="Wrap"/>
<WebView x:Name="webView" Width="800" Height="500"/>
<StackPanel x:Name="spButton" Orientation="Horizontal">
</StackPanel>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Column="2">
<TextBlock FontSize="26.667" FontWeight="Light" Text="{Binding Description}" TextWrapping="Wrap"/>
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Column="4">
<TextBlock FontSize="26.667" FontWeight="Light" Text="{Binding Tag}" TextWrapping="Wrap"/>
</StackPanel>
</Grid>
<VisualStateManager.VisualStateGroups>
<!-- Visual states reflect the application's view state inside the FlipView -->
<VisualStateGroup x:Name="ApplicationViewStates">
<VisualState x:Name="FullScreenLandscape"/>
<VisualState x:Name="Filled"/>
<!-- Respect the narrower 100-pixel margin convention for portrait -->
<VisualState x:Name="FullScreenPortrait">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="richTextColumns" Storyboard.TargetProperty="Margin">
<DiscreteObjectKeyFrame KeyTime="0" Value="97,0,87,57"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="image" Storyboard.TargetProperty="MaxHeight">
<DiscreteObjectKeyFrame KeyTime="0" Value="400"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<!-- When snapped, the content is reformatted and scrolls vertically -->
<VisualState x:Name="Snapped">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="richTextColumns" Storyboard.TargetProperty="Margin">
<DiscreteObjectKeyFrame KeyTime="0" Value="17,0,17,57"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="scrollViewer" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource VerticalScrollViewerStyle}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="richTextBlock" Storyboard.TargetProperty="Width">
<DiscreteObjectKeyFrame KeyTime="0" Value="280"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="image" Storyboard.TargetProperty="MaxHeight">
<DiscreteObjectKeyFrame KeyTime="0" Value="160"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ScrollViewer>
</UserControl>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
<VisualStateManager.VisualStateGroups>
<!-- Visual states reflect the application's view state -->
<VisualStateGroup x:Name="ApplicationViewStates">
<VisualState x:Name="FullScreenLandscape"/>
<VisualState x:Name="Filled"/>
<!-- The back button respects the narrower 100-pixel margin convention for portrait -->
<VisualState x:Name="FullScreenPortrait">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<!-- The back button and title have different styles when snapped -->
<VisualState x:Name="Snapped">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
My apps synthesis clips, each items is a game, each games have views, in StackPanel spButton I want to add buttons as a link to play videos. How can add dynamic buttons in file .cs
This is typical case of invoking controls method through View Model.
To accomplish this, You need to following steps
1. Define an interface INavigatable that expose Navigate event
2. Implement the interface in ViewModel.
3. In the View Code behind, check if DataContext implements INavigatable interface.
4. If step 3 is true, Subscribe to View Model event in view code behind.
Example.
Step 1:
class NavigateEventArgs:EventArgs
{
public string Target {get;set;}
}
public delegate void NavigateEventHandler (object sender, NavigateEventArgs nargs);
public interface INavigatable
{
event NavigateEventHandler Navigate;
}
Step 2:
class MyViewModel : INavigatable
{
public event NavigateEventHandler Navigate;
MyViewModel()
{
NavigateCommand = new DelegateCommand(() =>
{
RaiseNavigateEvent();
}) ;
}
void RaiseNavigateEvent()
{
var temp = Navigate;
if (temp != null)
{
temp(new NavigateEventArgs{Target = Link});
}
}
public string Link {get;set;} // this should be bound to Button.Content (preferably in XAML)
public ICommand NavigateCommand{ get;set;}
}
Step 3/4:
public class MyView : Window
{
public MyView()
{
...
Load += (s,e)=>
{
if (this.DataContext is INavigatable)
{
((INavigatable)(this.DataContext)).Navigate += (s1,e1) => webView.Navigate(e1.Target);
}
}
}
}
As an improvement, subscribe/unsubscribe the Navigate event in DataContextChanged event instead of Load event

Categories

Resources