UWP Hamburger navigation menu error when using visual triggers - XAML - c#

I'm creating a Hamburger navigation UI for an UWP using Visual triggers and I get this error.
"An animation is trying to modify an object named 'HamburgerButtonMobile', but no such object can be found in the Page."
This is my code
<VisualState.Setters>
<Setter Target="HamburgerButtonMobile.Visibility" Value="Collapsed" />
</VisualState.Setters>
<Pivot x:Name="MoviesPivot" Title="MOVIES">
<Pivot.TitleTemplate>
<DataTemplate>
<RelativePanel>
<TextBlock Text="{Binding}" FontSize="72" Foreground="#FF21B255" FontWeight="Light" RelativePanel.AlignRightWithPanel="True" x:Name="titleName"/>
<Button x:Name="HamburgerButtonMobile" FontFamily="Segoe MDL2 Assets" Content="" Width="50" Height="50" Background="Transparent" Click="HamburgerButtonMobile_Click" RelativePanel.LeftOf="titleName" RelativePanel.AlignVerticalCenterWithPanel="True" />
</RelativePanel>
</DataTemplate>
</Pivot.TitleTemplate>

The reason that your Visual Trigger can't see the item is because the item you're trying to access lives inside of a DataTemplate. It 'Doesn't Exist' yet
I THINK what you want to do is add the visual trigger to the RelativePanel.
Honestly it's hard to say without seeing more code.
<RelativePanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="BlahNameState">
<VisualState.Setters>
<Setter Target="HamburgerButtonMobile.Visibility" Value="Collapsed" />
</VisualState.Setters>

Related

Proper way to add an AutoSuggestBox to Hamburger Navigation?

I'm just starting to learn UWP and xaml. What is the proper way to add a AutoSuggestBox to the Side Navigation panel? (Sorry for the bad code formatting in advance, copy and paste wasn't great)
My Main.xaml has an AutoSuggestArea that I have set to Visible
</VisualStateGroup>
<VisualStateGroup x:Name="AutoSuggestGroup">
<VisualState x:Name="AutoSuggestBoxVisible"/>
<VisualState x:Name="AutoSuggestBoxCollapsed">
<VisualState.Setters>
<Setter Target="AutoSuggestArea.Visibility" Value="Visible"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
and in the Grid for the AutoSuggestArea I have defined an AutoSuggestBox
<Grid x:Name="AutoSuggestArea" Height="44" Grid.Row="3" VerticalAlignment="Center">
<ContentControl x:Name="PaneAutoSuggestBoxPresenter" Content="{TemplateBinding AutoSuggestBox}" HorizontalContentAlignment="Stretch" IsTabStop="False" Margin="16,0,16,0" VerticalContentAlignment="Center"/>
<Button x:Name="PaneAutoSuggestButton" Content="" MinHeight="44" Style="{TemplateBinding PaneToggleButtonStyle}" Visibility="Collapsed" Width="{TemplateBinding CompactPaneLength}"/>
<AutoSuggestBox Width="234" VerticalAlignment="Center"
HorizontalAlignment="Center"
PlaceholderText="Search" Name ="boxS"
QuerySubmitted="AutoSuggestBox_QuerySubmitted"
TextChanged="AutoSuggestBox_TextChanged">
<AutoSuggestBox.TextBoxStyle>
<Style TargetType="TextBox">
<Setter Property="IsHandwritingViewEnabled" Value="False"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
</AutoSuggestBox.TextBoxStyle>
<AutoSuggestBox.QueryIcon>
<SymbolIcon Symbol="Find" Foreground="Black">
<SymbolIcon.RenderTransform>
<CompositeTransform ScaleX="1" ScaleY="1"/>
</SymbolIcon.RenderTransform>
</SymbolIcon>
</AutoSuggestBox.QueryIcon>
</AutoSuggestBox>
</Grid>
What I want is basically Identical Behaviour as the Groove Music app on Windows, where the Search bar disappears as the Nav View is closed or Minimized.
Instead I get this
I am assuming you meant NavigationView by NavigationPanel.
This is not how you put an AutoSuggestBox in NavigationView. NavigationView has an NavigationView.AutoSuggestBox property. You just set an AutoSuggestBox on this property, and every thing will work as expected. Like this:
<NavigationView>
<NavigationView.AutoSuggestBox>
<AutoSuggestBox x:Name="NavViewSearchBox" QueryIcon="Find"/>
</NavigationView.AutoSuggestBox>
</NavigationVew>
You don't have to hide/show this AutoSuggestBox yourself. NavigationView will automatically do this for you. Also, you don't have to put thie AutoSuggestBox inside any grid or anything.

Content Control and Button Flyout

I am making a UWP app and I have come across a problem. I want to make a StackPanel which hosts two ComboBoxes and one TextBox. I can show it in the app if I create it inside the Grid and it works as expected. But for smaller screen devices I want to show a Button in place of the StackPanel and move the StackPanel to the button flyout.
I have tried to add the StackPanel to a ContentControl and then set it as the Flyout but it doesn't work. Flyout needs a FlyoutPresenter control to be able to show the flyout.
I don't want to create multiple StackPanel controls because of the naming collisions, but I do want it simple so I need to make changes to one side of the controls and when the user switches the screen or the view the smaller screen also shows the same stuff.
Can someone help me here? Maybe just point me in the right direction so I can figure it out on my own. Any help will be appreciated. Thanks
StackPanel control:
<StackPanel Orientation="Vertical"
x:Name="PageOptionsPanel"
HorizontalAlignment="Right">
<AppBarButton Label="Refresh"
Icon="Refresh"
Tapped="PageOptions_Tapped"/>
<RelativePanel Margin="10,0">
<TextBlock Text="Sort by:"
Name="SortText"
RelativePanel.AlignVerticalCenterWithPanel="True"
Margin="0,0,5,0"/>
<ComboBox RelativePanel.RightOf="SortText"
x:Name="MSortingBox"
ItemsSource="{Binding EnSortList}"
RelativePanel.AlignVerticalCenterWithPanel="True"
SelectionChanged="MSortingBox_SelectionChanged"
Width="120"/>
</RelativePanel>
<RelativePanel Margin="10,0">
<TextBlock Text="Country: "
Name="CountryText"
RelativePanel.AlignVerticalCenterWithPanel="True"
Margin="0,0,5,0"/>
<ComboBox RelativePanel.RightOf="CountryText"
x:Name="MCountryBox"
ItemsSource="{Binding EnCountryList}"
RelativePanel.AlignVerticalCenterWithPanel="True"
SelectionChanged="MCountryBox_SelectionChanged"
Width="120"/>
</RelativePanel>
</StackPanel>
Flyout control:
<Button>
<Button.Flyout>
<Flyout Placement="Left"
x:Name="MOptionsFlyout"
Content="{StaticResource PageOptionsFlyout}"
Opened="MOptionsFlyout_Opened">
</Flyout>
</Button.Flyout>
</Button>
If I understand your question correctly, you want to share the XAML for your Options layout between the main page and a flyout, based on the size of the page (for phone vs tablet). You can do this by creating a DataTemplate with the layout and adding it to the page's resource dictionary. Then it can be referenced in multiple places.
Here's the code below that does that. It also hides and shows the pieces based on adaptive triggers.
<Page.Resources>
<DataTemplate x:Key="PageOptionsTemplate">
<StackPanel
x:Name="PageOptionsPanel"
HorizontalAlignment="Right"
Orientation="Vertical">
<AppBarButton
Icon="Refresh"
Label="Refresh" />
<RelativePanel Margin="10,0">
<TextBlock
Name="SortText"
Margin="0,0,5,0"
RelativePanel.AlignVerticalCenterWithPanel="True"
Text="Sort by:" />
<ComboBox
x:Name="MSortingBox"
Width="120"
RelativePanel.AlignVerticalCenterWithPanel="True"
RelativePanel.RightOf="SortText"/>
</RelativePanel>
<RelativePanel Margin="10,0">
<TextBlock
Name="CountryText"
Margin="0,0,5,0"
RelativePanel.AlignVerticalCenterWithPanel="True"
Text="Country: " />
<ComboBox
x:Name="MCountryBox"
Width="120"
RelativePanel.AlignVerticalCenterWithPanel="True"
RelativePanel.RightOf="CountryText"
/>
</RelativePanel>
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Name="OptionsFlyoutButton" Content="Show Me" Visibility="Collapsed">
<Button.Flyout>
<Flyout>
<ContentControl ContentTemplate="{StaticResource PageOptionsTemplate}"/>
</Flyout>
</Button.Flyout>
</Button>
<ContentControl Name="OptionsInLine" Visibility="Visible" ContentTemplate="{StaticResource PageOptionsTemplate}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="320"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="OptionsInLine.Visibility" Value="Collapsed"/>
<Setter Target="OptionsFlyoutButton.Visibility" Value="Visible"/>
</VisualState.Setters>
</VisualState>
<VisualState>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="720"/>
</VisualState.StateTriggers>
<VisualState.Setters>
</VisualState.Setters>
</VisualState>
<VisualState>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1024"/>
</VisualState.StateTriggers>
<VisualState.Setters>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
You can also move the DataTemplate out to the application level ResourceDictionary, so that it can be shared between multiple pages.
Finally, another option is to create a user control (using the uwp item template) for this. I recommend creating that if you needed more control over the layout, wanted to encapsulate the logic too, and share it across multiple apps.
For your example, the shared DataTemplate is the easiest path.
Just do this:
<Button Content="Show Me">
<Button.Flyout>
<Flyout>
<StackPanel
x:Name="PageOptionsPanel"
HorizontalAlignment="Right"
Orientation="Vertical">
<AppBarButton
Icon="Refresh"
Label="Refresh" />
<RelativePanel Margin="10,0">
<TextBlock
Name="SortText"
Margin="0,0,5,0"
RelativePanel.AlignVerticalCenterWithPanel="True"
Text="Sort by:" />
<ComboBox
x:Name="MSortingBox"
Width="120"
RelativePanel.AlignVerticalCenterWithPanel="True"
RelativePanel.RightOf="SortText"/>
</RelativePanel>
<RelativePanel Margin="10,0">
<TextBlock
Name="CountryText"
Margin="0,0,5,0"
RelativePanel.AlignVerticalCenterWithPanel="True"
Text="Country: " />
<ComboBox
x:Name="MCountryBox"
Width="120"
RelativePanel.AlignVerticalCenterWithPanel="True"
RelativePanel.RightOf="CountryText"
/>
</RelativePanel>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
to get this:
When using the you get an auto display flyout that is shown whenever a user clicks the button, no code needed.
but to add content to that flyout, you need to have another element in it, then the stackpanel goes into it.
Hope this helps you.

Repositioning Children in RelativePanel through VisualStates

I have Relative Panel with a bunch of Children in it. I want to change the position of children by AdoptiveTrigger in VisualStates.
The problem is when i want to change an element position from Below of other element to right of that element, I've to remove the value of Below Attached Property and then set the RightOf property to make it work,otherwise it crashes the app.
Now i want to now how to remove that Below Value?
I've tried to
a.reset the binding in Properties Window for each state and then assigning my values
b.setting that value to empty string like "";
c.Ignoring that property.
None of these worked!
please help me!
Setting the attached property RelativePanel.Below to empty can work. Besides this we can also slove this problem by setting AlignTopWith or AlignVerticalCenterWith property.
This works because the priority of AlignTopWith is higher than Below and for AlignVerticalCenterWith property, it is applied if there is no conflict. As my test, AlignVerticalCenterWith's priority is also higher than Below.
For more information, please see the Conflicting relationships section in RelativePanel class.
Following is the sample I used to test:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="600" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="BlueRect.(RelativePanel.Below)" Value="" />
<Setter Target="GreenRect.(RelativePanel.RightOf)" Value="BlueRect" />
<Setter Target="GreenRect.(RelativePanel.Below)" Value="RedRect" />
<!--<Setter Target="GreenRect.(RelativePanel.AlignVerticalCenterWith)" Value="BlueRect" />-->
<!--<Setter Target="GreenRect.(RelativePanel.AlignTopWith)" Value="BlueRect" />-->
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<RelativePanel>
<Rectangle x:Name="RedRect"
Width="100"
Height="100"
Fill="Red" />
<Rectangle x:Name="BlueRect"
Width="100"
Height="200"
Fill="Blue"
RelativePanel.Below="RedRect"
RelativePanel.RightOf="RedRect" />
<Rectangle x:Name="GreenRect"
Width="100"
Height="100"
Fill="Green"
RelativePanel.Below="BlueRect"
RelativePanel.RightOf="RedRect" />
</RelativePanel>
</Grid>
It works like:
You can do
<Setter Target="SomeElement.(RelativePanel.Below)" Value="{x:Null}" />

Simple way to change appearance of a TextBlock on hover?

I'm making a zoom control (Slider) with a TextBlock indicator that tells you want the current scale factor is (kinda like in the bottom-right corner of Word).
I'm a couple days into learning WPF, and I've been able to figure out how to do most of it, but I get the sense there's a much simpler way (one which, perhaps, only involves XAML-side code rather than a bunch of mouse events being captures.
I'd like for a the text to be underlined when hovered over (to imply clickability) and for a click to reset the slider element to 1.0.
Here's what I have:
<StatusBarItem Grid.Column="1" HorizontalAlignment="Right">
<Slider x:Name="mapCanvasScaleSlider" Width="150" Value="1" Orientation="Horizontal" HorizontalAlignment="Left"
IsSnapToTickEnabled="True" Minimum="0.25" Maximum="4" TickPlacement="BottomRight"
Ticks="0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5, 3, 4"/>
</StatusBarItem>
<StatusBarItem Grid.Column="2">
<TextBlock Name="zoomIndicator" Text="{Binding ElementName=mapCanvasScaleSlider,Path=Value,StringFormat=0%}"
MouseDown="ResetZoomWindow" MouseEnter="zoomIndicator_MouseEnter" MouseLeave="zoomIndicator_MouseLeave"
ToolTip="Zoom level; click to reset"/>
</StatusBarItem>
private void ResetZoomWindow(object sender, MouseButtonEventArgs args)
{
mapCanvasScaleSlider.Value = 1.0;
}
private void zoomIndicator_MouseLeave(object sender, MouseEventArgs e)
{
zoomIndicator.TextDecorations = TextDecorations.Underline;
}
private void zoomIndicator_MouseLeave(object sender, MouseEventArgs e)
{
zoomIndicator.TextDecorations = null;
}
I feel as though there's a better way to do this through XAML rather than to have three separate .cs-side functions.
You could use a style trigger for the text block, like described in this other post How to set MouseOver event/trigger for border in XAML?
Working solution:
<StatusBarItem Grid.Column="2">
<TextBlock Name="zoomIndicator" Text="{Binding ElementName=mapCanvasScaleSlider,Path=Value,StringFormat=0%}"
MouseDown="ResetZoomWindow" ToolTip="Zoom level; click to reset">
<TextBlock.Style>
<Style>
<Setter Property="TextBlock.TextDecorations" Value="" />
<Style.Triggers>
<Trigger Property="TextBlock.IsMouseOver" Value="True">
<Setter Property="TextBlock.TextDecorations" Value="Underline" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StatusBarItem>
Still have to reset the zoom level manually (I think), though.
You can use VisualState (if you're using Blend its easy to edit).
Personally I prefer style triggers, unless I have to add StoryBoard animation - then I offen use VisualState
about VisualState
Typically, you wouldn't want to use a TextBlock as a button (although of course you can). You may want to consider using a more appropriate control like Button or HyperlinkButton, which have the basic mouse event handling already wired up. You can then apply whatever styles you like. A Button control, for example, can be easily styled re-templated as a TextBlock with underline on mouse-over:
<Style TargetType="Button" x:Key="LinkButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard Duration="0:0:0.1">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="content" Storyboard.TargetProperty="TextDecorations">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<TextDecorationCollection>Underline</TextDecorationCollection>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBlock x:Name="content" Text="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Use it by referencing the style key:
<Button Content="click" Style="{StaticResource LinkButtonStyle}" />
Using this approach (rather than the alternative of adding triggers to a TextBlock) brings some advantages, which are built in to the Button control.
You can apply styles to compound states like Pressed
You can use the Click event, and its related Command property

Can Someone Explain How the Grid Project works in Windows 8

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.

Categories