I have a ScrollViewer that contains a StackedPanel with rectangles laid out horizontally. I want to be able to scroll horizontally, but this isn't happening for me. Here is my XAML:
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="BlastSwing.GroupedItemsPage"
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:BlastSwing"
xmlns:data="using:BlastSwing.Data"
xmlns:common="using:BlastSwing.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 grouped items displayed by this page, bound to a subset
of the complete item list because items in groups cannot be virtualized
-->
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="TopItems"
d:Source="{Binding AllGroups, 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}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Back button and page title -->
<TextBlock x:Name="pageTitle" Text="Blast Swing" Style="{StaticResource PageHeaderTextStyle}" Margin="40,0,-10,53"/>
<ScrollViewer HorizontalAlignment="Left" Height="628" Grid.Row="1" VerticalAlignment="Top" Width="1366" RenderTransformOrigin="0.476999998092651,0.998000025749207" VerticalScrollMode="Disabled" Margin="-22,0,0,0" HorizontalScrollMode="Auto">
<StackPanel Height="568" Width="1313" RenderTransformOrigin="-0.0179999992251396,0.512000024318695" Orientation="Horizontal">
<Rectangle Fill="#FF974B55" Height="568" Stroke="Black" VerticalAlignment="Top" Width="371"/>
<Rectangle Fill="#FF17179C" Height="568" Stroke="Black" VerticalAlignment="Top" Width="371"/>
<Rectangle Fill="#FF8D2B80" Height="568" Stroke="Black" VerticalAlignment="Top" Width="371"/>
<Rectangle Fill="#FF301D2F" Height="568" Stroke="Black" VerticalAlignment="Top" Width="371"/>
<Rectangle Fill="#FFF4F4F5" Height="568" Stroke="Black" VerticalAlignment="Top" Width="371"/>
</StackPanel>
</ScrollViewer>
<!-- Back button and page title -->
<!-- Horizontal scrolling grid used in most view states -->
<!-- Vertical scrolling list only used when snapped -->
<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="pageTitle" Storyboard.TargetProperty="Style">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</common:LayoutAwarePage>
You are setting Scrollviewer's Width="1366" which is more than your child stackpanel Width="1313".
If you want to see the horizontal scrollbar then you might want to set the size of ScrollViewer less than 1313 and it should be able to display the horizontal scrollbar as it is not able to display the content fully.
Set the HorizontalScrollBarVisibility property on the ScrollViewer to Visible or Auto.
You are setting the Width of your StackPanel manually and it is less than the total of its children.
Related
I've got a bit of a problem with my images in a WPF Vb.net based window.
If the image control is not directly in the centre of the window with a margin of 0, it will not show at runtime.
Here is the XAML code for both images:
<Image x:Name="loaderlogo" Height="55" Margin="1825,985,40,40" Width="55" Stretch="Fill"/>
<Image x:Name="tips" Height="128" Margin="0,732,0,220" Width="1920" Stretch="Fill" Opacity="0.9"/>
Both are contained inside a grid with one row and one column (the default grid that is there when you create a new window).
These images will not appear if this code is run however if i make the margins
Margin="0"
They will appear just fine, but in the very center of the control
How can i make it so that the controls still appear if the margins are not zero (if i move the images' location anywhere but the center of the form?
The code i use to fetch the image files is:
UseLayoutRounding = True
Dim exepath As String = System.AppDomain.CurrentDomain.BaseDirectory
loaderlogo.Source = New BitmapImage(New Uri(exepath & "loaderlogo.png", UriKind.Absolute))
tips.Source = New BitmapImage(New Uri(exepath & "tips.png", UriKind.Absolute))
The images work perfectly fine if dead center so I believe the problem is with the XAML but I am not sure where. I have changed the horizontal/vertical alignment but the images still appear in the center as long as the margin is 0.
EDIT: Below are the positions where I would like the controls to be, the bottom left is the 'loaderlogo' and the band across the window is the 'tips' control.
tips band position
loaderlogo position
EDIT 2: Below is the entire XAML code for the window:
<Window x:Class="loadingwindow" UseLayoutRounding="True"
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"
xmlns:local="clr-namespace:applicationname"
mc:Ignorable="d"
Title="loadingwindow" Height="1080" Width="1920" AllowsTransparency="True" WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" WindowState="Maximized" Loaded="Window_Loaded">
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="00:00:01" Storyboard.TargetProperty="Opacity" From="0" To="1" Completed="DoubleAnimation_Completed"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Image x:Name="loaderlogo" Height="55" Margin="1825,985,40,40" Width="55" Stretch="Fill"/>
<Image x:Name="tips" Height="128" Margin="0,732,0,220" Width="1920" Stretch="Fill" Opacity="0.9"/>
</Grid>
Large margins are the worst way to position elements. The better approach is to use correct layout panel and correct alignments for elements. Small margin is fine to add some space between elements.
Grid panel is usually used with many RowDefinitions and ColumnDefinitions. Elements are placed in different rows and columns, and resulting layout is adaptive to size changes
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image x:Name="tips" Grid.Row="1" Height="128" Width="1920" Stretch="Fill" Opacity="0.9"/>
<Image x:Name="loaderlogo" Grid.Row="2" Height="55" Width="55" Margin="10"
HorizontalAlignment="Right" Stretch="Fill"/>
</Grid>
I am trying to create a user control similar to a stock ticker. It will slowly scroll the items to the left. So far I am unable to get something going because:
I am new to WPF/XAML and everywhere I search seems to apply to
silvelight
I am using an ItemTemplate within a ItemsControl, and cant find any
examples showing how to add a storyboard for a item within an item template.
here is my XAML:
<UserControl x:Class="WpfApplication.Ctrls.MessageTicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:ctrls="clr-namespace:WpfApplication.Ctrls"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Background="Honeydew">
<ItemsControl ItemsSource="{Binding}" Name="_items">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="_panel">
<Grid.Triggers>
<EventTrigger RoutedEvent="Grid.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Grid.RenderTransform).(TranslateTransform.X)"
Storyboard.TargetName="_panel"
From="0"
To="360"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Word}" Grid.Column="0" Margin="0" FontWeight="Normal" FontFamily="Segoe UI Semibold"/>
<TextBlock Text="{Binding Path=Percent}" Grid.Column="1" Margin="5,0,3,0" FontFamily="Segoe UI Mono" Foreground="Blue"/>
<Polygon Points="0,10 5,0 10,10" Stroke="Black" Fill="Green" Grid.Column="2" Margin="0,3,10,0"/>
<Polygon Points="5,10 10,0 0,0" Stroke="Black" Fill="Red" Grid.Column="2" Visibility="Collapsed"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
From what I have read, I should be putting the storyboard within the template. When I add a new item to the ItemsControl, nothing happens. I need to have it start at the end of the ItemsControl and scroll to the right all the way to the beginning of the ItemsControl.
Ok so you're close, but you're missing some key things that might explain why it's not firing as you'd expect.
So your first issue lies with how you're using _panel. We'll want to actually move that to an RenderTransform on this Grid that's acting as your parent.
So instead of;
<Grid x:Name="_panel">
We'll say;
<Grid>
<Grid.RenderTransform>
<TranslateTransform x:Name="_panel">
</Grid.RenderTransform>
...
Because your TargetProperty setting in your storyboard isn't going to magically append that Transform on demand like it looks you're thinking it might (at least I've never seen it done that way I don't think).
So we have that, now let's go talk to that Transform via your Storyboard and have it talk to an actual property of your Transform thusly;
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="X"
Storyboard.TargetName="_panel">
<SplineDoubleKeyFrame KeyTime="0:0:0" Value="360" />
</DoubleAnimation>
</Storyboard>
So what we're doing is basically saying "HEY _panel, guess what? You get to animate, and before you start I want you to know you're moving 360 across your X axis"
We could add a keytime here to make this happen over more keyframes to allow it to fill in the blanks of an actual animation sequence (your ticker anime, hint hint) but for now, we're just telling that bugger to move.
Other than that, you should work. Hope this helps, cheers.
Oh and PS, you'd be surprised how much XAML can work between WPF/SL/WP, etc. etc. if you just know the fundamentals. Best of luck!
I have a ContentControl that I'm styling with a DataTemplate. I'd like to be able to define an animation outside of the ContentControl that animates elements in the DataTemplate. This XAML is a small, simplified example of my scenario:
<UserControl x:Class="StoryboardTesting.Stage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d">
<UserControl.Resources>
<DataTemplate x:Key="MyControlTemplate">
<StackPanel>
<TextBlock x:Name="TheBlock1" Text="Foo!" />
<TextBlock x:Name="TheBlock2" Text="Bar!" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="ValueStates">
<VisualState Name="ToState">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MyContentControl"
Storyboard.TargetProperty="(UIElement.Opacity)"
Duration="0:0:1"
To="0" />
</Storyboard>
</VisualState>
<VisualState Name="FromState" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Canvas>
<ContentControl x:Name="MyContentControl"
ContentTemplate="{StaticResource MyControlTemplate}" />
</Canvas>
</Grid>
</UserControl>
I'd like the animation to be able to target either TextBox in the template (instead of "MyContentControl"), either by position or name. I'm starting the animation in the UserControl's code-behind with a call like this:
VisualStateManager.GoToElementState(this, "ToState", true);
When I run this (replacing "MyContentControl" with "TheBlock"), I get the following:
InvalidOperationException: 'TheBlock1' name cannot be found in the name scope of 'StoryboardTesting.Stage'.
Which makes sense. Is there a way to address either block using property names? I need to avoid codebehind since this is XAML that is being generated at runtime.
I'd highly suggest you to learn using Blend when working on WPF projects. While XAML by keyboard skills are indeed useful, Blend is also very helpful. It took me about 5 minutes to build the following example for you, it's a DataTemplate which has states.
(first I created an empty DataTemplate, then I edited in Blend)
User can press any of the 2 buttons on the bottom and the current state will be changed.
As you'll see below, behaviors proven to be really helpful for handling states, no code-behind at all.
XAML:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:wpfApplication3="clr-namespace:WpfApplication3"
Title="MainWindow"
Width="525"
Height="350">
<Window.Resources>
<wpfApplication3:MyObject x:Key="MyObject1" />
<DataTemplate x:Key="Template1" DataType="wpfApplication3:MyObject">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="37*" />
<RowDefinition Height="13*" />
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="Red">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="button" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="Red" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Green">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="button" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="Lime" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Button x:Name="button"
Grid.RowSpan="1"
Grid.ColumnSpan="2"
Width="100"
Height="100"
Margin="2"
Content="Button"
FontSize="26.667" />
<Button Grid.Row="1"
Width="Auto"
Margin="2"
Content="State1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:GoToStateAction StateName="Red" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button Grid.Row="1"
Grid.Column="1"
Width="Auto"
Margin="2"
Content="State2">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:GoToStateAction StateName="Green" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<ContentControl Content="{StaticResource MyObject1}" ContentTemplate="{StaticResource Template1}" />
</Grid>
</Window>
Code-behind:
namespace WpfApplication3
{
public partial class MainWindow
{
public MainWindow() {
InitializeComponent();
}
}
internal class MyObject
{
public string Category { get; set; }
public int Value { get; set; }
}
}
EDIT
To answer the point of your question, those states belong to the DataTemplate; defining these states outside of it doesn't make any sense and as you've experienced it is not even possible, and this is for a good reason !
Imagine that you use this template in 2 different places, would they share the same state ? Of course no, so the states have to be defined inside it, not outside.
I am looking at the windows 8 grid project that comes with VS2012 and trying to understand it. I don't know too much about XAML so I getting quite easily lost of where binding code is happening and such.
<Page.Resources>
<!--
Collection of grouped items displayed by this page, bound to a subset
of the complete item list because items in groups cannot be virtualized
-->
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="TopItems"
d:Source="{Binding AllGroups, 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}">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Horizontal scrolling grid used in most view states -->
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.RowSpan="2"
Padding="116,137,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="1,0,0,6">
<Button
AutomationProperties.Name="Group Title"
Click="Header_Click"
Style="{StaticResource TextPrimaryButtonStyle}" >
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" Margin="3,-7,10,10" Style="{StaticResource GroupHeaderTextStyle}" />
<TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-7,0,10" Style="{StaticResource GroupHeaderTextStyle}"/>
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
<!-- Vertical scrolling list only used when snapped -->
<ListView
x:Name="itemListView"
AutomationProperties.AutomationId="ItemListView"
AutomationProperties.Name="Grouped Items"
Grid.Row="1"
Visibility="Collapsed"
Margin="0,-10,0,0"
Padding="10,0,0,60"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource Standard80ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="7,7,0,0">
<Button
AutomationProperties.Name="Group Title"
Click="Header_Click"
Style="{StaticResource TextPrimaryButtonStyle}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" Margin="3,-7,10,10" Style="{StaticResource GroupHeaderTextStyle}" />
<TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-7,0,10" Style="{StaticResource GroupHeaderTextStyle}"/>
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
<!-- 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="{StaticResource AppName}" Grid.Column="1" IsHitTestVisible="false" Style="{StaticResource PageHeaderTextStyle}"/>
</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,137,10,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>
The first area I don't understand is this
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="TopItems"
d:Source="{Binding AllGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/>
I don't get where this Source="{Binding Groups}" is actually coming from (I am not even sure how to find the code F12 does not work).
Same with the d:Source not sure 100% what is going on there as well.
The next part is in the gridview and again with the binding.
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.RowSpan="2"
Padding="116,137,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
I see that Items Source is using that groupItemsViewSource but not sure how it is parsing the data into the grid look but not sure how.
The next part I don't get is how does it figure out what layout to use. I see this in the comments
<!-- Horizontal scrolling grid used in most view states -->
<!-- Vertical scrolling list only used when snapped -->
I am sure if I look even deeper into it I will find more I don't understand but maybe when I understand this stuff I will understand more(especially once I understand this binding stuff)
I don't get where this Source="{Binding Groups}" is actually coming
from (I am not even sure how to find the code F12 does not work).
Note at the top of the page:
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
which sets the context for the binding on that page to the DefaultViewModel property of the page. In the code behind for the page you'll see
this.DefaultViewModel["Groups"] = sampleDataGroups;
where sampleDataGroups is a list (IEnumerable) of groups (type SampleDataGroup) returned from a method call. Now you also have,
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="TopItems"
d:Source="{Binding AllGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/>
and here "Groups" refers to the key that indexes the DefaultViewModel, so it's going to use that subset of the DefaultViewModel. Furthermore, each item in the CollectionViewSource itself contains a collection, and those collections are surfaced to the binding engine at whatever property ItemsPath specifies, namely, TopItems.
Now from the GridView binding:
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.RowSpan="2"
Padding="116,137,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
you noted that the data is coming from that specific instance of a CollectionViewSource named groupedItemsViewSource (which in this case is equivalent to this.DefaultViewModel["Groups"]). If you look at the header template a bit later, you'll see:
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" Margin="3,-7,10,10" Style="{StaticResource GroupHeaderTextStyle}" />
...
The Title binding refers to the property of an element in the ItemsSource collection, so this.DefaultViewModel["Groups"][i].Title
ItemTemplate="{StaticResource Standard250x250ItemTemplate}" in the GridView binding governs how the inner collection items are displayed. You'll have to crack that style open (in Common/StandardStyles.xaml) to see that it references properties of a SampleDataItem, essentially leading to this.DefaultViewModel["Groups"][i].TopItems[j].
The d: prefix refers to design time data (well, a namespace that includes classes that manage it); it's what allows you do see the data in the designer without running your application. So at design time the data you are seeing actually comes from SampleDataSource.AllGroups.
As for the comments about scrolling, that gets into the VisualStateManager, each state essentially being a different take on the UI; states transition via a bit of code you can find inside of LayoutAwarePage.cs look for GotoState.
I don't get where this Source="{Binding Groups}" is actually coming from
Bindings target the DataContext of the element -- to find it, you typically scan up the XAML to find where DataContext was last set. So in this case, it must either set on the Page element somehow. (The DataContext can also be set from code-behind, although I'd be surprised if that were the case in the VS sample project.)
Same with the d:Source not sure 100% what is going on there as well.
The d prefix is referring to design-time data. Check for the SampleDataSource, that's where you'll find the design-time instance of AllGroups.
not sure how it is parsing the data into the grid
The Grid auto-generates its columns based on the properties of its row data type.
I am trying out a tutorial on WIndows 8. I need to add a Navigation Bar. The steps are given below;
The following is from the tutorial.
In Solution Explorer, double-click MainPage.xaml to open it.
In the Document Outline, select the "pageRoot" element.
In the Properties panel, click the Properties button () to show the Properties view.
Under Common in the Properties panel, find the TopAppBar property.
Click the New button next to TopAppBar. An AppBar control is added to the page.
In the Document Outline, expand the TopAppBar property.
Select the "photoPageButton" element, drag it onto the AppBar, and drop it.
Under Layout in the Properties panel, set the HorizontalAlignment property to Right ().
Press F5 to build and run the app. To test the app bar, right-click on the main page. The app bar opens at the top of the screen.
I Double-clicked on the MainPage.xaml, and then in the Document Outline i selected pageRoot. and in the properties Window expanded Common and i clicked on New next to TopAppBar.
It added several other Fields below it. Allow Drop, Background and Cache Mode are some of it. Then in the Document Outline i dragged the button to the AppBar under TopAddBar. Changed the HorizontalAlignment to Right, build and executed the application. But i don't see the button added to the top Navigation bar. What have i done wrong here ?
UPDATE
<Page.Resources>
<!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
<x:String x:Key="AppName">My Application</x:String>
</Page.Resources>
<common:LayoutAwarePage.TopAppBar>
<AppBar Background="#E5A41D1D" AllowDrop="True" BorderBrush="#E5C5A7A7" HorizontalAlignment="Right">
<Button Content="Next Page
" HorizontalAlignment="Right" VerticalAlignment="Stretch" Width="230" Height="70" Background="#FF12668D" FontFamily="Shruti" FontSize="36" Click="Button_Click_2"/>
</AppBar>
</common:LayoutAwarePage.TopAppBar>
<!--
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}" Background="#FF282D40">
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Back button and page title -->
<!-- Back button and page title -->
<!-- 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="Welcome !!! " Style="{StaticResource PageHeaderTextStyle}" Foreground="#DE2374AC"/>
</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>
</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>
You're following this tutorial here, correct? It looks like you've dragged the wrong button to your TopAppBar.
The button you should be dragging is named photoPageButton (its x:Name attribute). Instead, the button you've got in your TopAppBar doesn't have a name, and presents the text "Next Page".
Your XAML markup for the TopAppBar should look something like this after you've dragged the photoPageButton to the TopAppBar:
<common:LayoutAwarePage.TopAppBar>
<AppBar HorizontalAlignment="Right">
<Button x:Name="photoPageButton" Content="Go to photo page"/>
</AppBar>
</common:LayoutAwarePage.TopAppBar>
After you get a little farther in the tutorial and apply a style to the button, your markup for the TopAppBar will then look like this:
<common:LayoutAwarePage.TopAppBar>
<AppBar HorizontalAlignment="Right">
<Button x:Name="photoPageButton"
Click="photoPageButton_Click"
HorizontalAlignment="Right"
Style="{StaticResource PicturesAppBarButtonStyle}"/>
</AppBar>
</common:LayoutAwarePage.TopAppBar>
It's perfectly acceptable to have the other AppBar settings in there as well - Background, BorderBrush; these are harmless changes to the color - and AllowDrop defaults to true, I believe, so that's fine too.