Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

work

  • Loading branch information...
commit 9a504bfb20bc7acc101ee0fbcc092cdbaf2e6dfc 1 parent a33a5e1
Mikael Koskinen authored
Showing with 3,819 additions and 0 deletions.
  1. +46 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems.sln
  2. +2 −0  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems.sln.DotSettings.user
  3. +35 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/App.xaml
  4. +103 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/App.xaml.cs
  5. BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/DarkGray.png
  6. BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/LightGray.png
  7. BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/Logo.png
  8. BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/MediumGray.png
  9. BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/SmallLogo.png
  10. BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/SplashScreen.png
  11. BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/StoreLogo.png
  12. +76 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/BadPerformancePage.xaml
  13. +35 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/BadPerformancePage.xaml.cs
  14. +55 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/BindableBase.cs
  15. +21 −0 ...dView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/BooleanNegationConverter.cs
  16. +32 −0 ...w-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/BooleanToVisibilityConverter.cs
  17. +464 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/LayoutAwarePage.cs
  18. +12 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/ReadMe.txt
  19. +210 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/RichTextColumns.cs
  20. +1,829 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/StandardStyles.xaml
  21. +257 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/SuspensionManager.cs
  22. +74 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Data/VideoService.cs
  23. +82 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/GoodPerformancePage.xaml
  24. +59 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/GoodPerformancePage.xaml.cs
  25. +40 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/MovieDetailsPage.xaml
  26. +32 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/MovieDetailsPage.xaml.cs
  27. +88 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/MoviesVm.cs
  28. +18 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/MyTemplateSelector.cs
  29. +42 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Package.appxmanifest
  30. +29 −0 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Properties/AssemblyInfo.cs
  31. +178 −0 ...rformance-Problems/WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems.csproj
  32. BIN  ...Problems/WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems_TemporaryKey.pfx
46 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems.sln
View
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinRT-GridView-XAML-Performance-Problems", "WinRT-GridView-XAML-Performance-Problems\WinRT-GridView-XAML-Performance-Problems.csproj", "{DD6D0CB1-CB71-4AAA-93C2-16087384A618}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|ARM.ActiveCfg = Debug|ARM
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|ARM.Build.0 = Debug|ARM
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|ARM.Deploy.0 = Debug|ARM
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|x64.ActiveCfg = Debug|x64
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|x64.Build.0 = Debug|x64
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|x64.Deploy.0 = Debug|x64
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|x86.ActiveCfg = Debug|x86
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|x86.Build.0 = Debug|x86
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Debug|x86.Deploy.0 = Debug|x86
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|ARM.ActiveCfg = Release|ARM
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|ARM.Build.0 = Release|ARM
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|ARM.Deploy.0 = Release|ARM
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|x64.ActiveCfg = Release|x64
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|x64.Build.0 = Release|x64
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|x64.Deploy.0 = Release|x64
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|x86.ActiveCfg = Release|x86
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|x86.Build.0 = Release|x86
+ {DD6D0CB1-CB71-4AAA-93C2-16087384A618}.Release|x86.Deploy.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
2  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems.sln.DotSettings.user
View
@@ -0,0 +1,2 @@
+<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+ <s:Boolean x:Key="/Default/Environment/SearchAndNavigation/MergeOccurences/@EntryValue">False</s:Boolean></wpf:ResourceDictionary>
35 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/App.xaml
View
@@ -0,0 +1,35 @@
+<Application
+ x:Class="WinRT_GridView_XAML_Performance_Problems.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+
+ <Application.Resources>
+ <ResourceDictionary>
+ <ResourceDictionary.MergedDictionaries>
+ <ResourceDictionary Source="Common/StandardStyles.xaml"/>
+ </ResourceDictionary.MergedDictionaries>
+
+ <DataTemplate x:Key="MovieTemplate">
+ <Grid HorizontalAlignment="Left" Width="250" Height="250">
+ <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
+ <Image Source="{Binding Cover}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
+ </Border>
+ <StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
+ <TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
+ <TextBlock Text="{Binding Year}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
+ </StackPanel>
+ </Grid>
+ </DataTemplate>
+
+ <DataTemplate x:Key="MovieCategoryTemplate">
+ <Grid HorizontalAlignment="Left" Width="250" Height="250">
+ <StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
+ <TextBlock Text="{Binding}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
+ </StackPanel>
+ </Grid>
+ </DataTemplate>
+
+ <x:String x:Key="AppName">WinRT GridView Performance Problems</x:String>
+ </ResourceDictionary>
+ </Application.Resources>
+</Application>
103 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/App.xaml.cs
View
@@ -0,0 +1,103 @@
+using WinRT_GridView_XAML_Performance_Problems.Common;
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Windows.ApplicationModel;
+using Windows.ApplicationModel.Activation;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+// The Grid App template is documented at http://go.microsoft.com/fwlink/?LinkId=234226
+
+namespace WinRT_GridView_XAML_Performance_Problems
+{
+ /// <summary>
+ /// Provides application-specific behavior to supplement the default Application class.
+ /// </summary>
+ sealed partial class App : Application
+ {
+ /// <summary>
+ /// Initializes the singleton Application object. This is the first line of authored code
+ /// executed, and as such is the logical equivalent of main() or WinMain().
+ /// </summary>
+ public App()
+ {
+ this.InitializeComponent();
+ this.Suspending += OnSuspending;
+ }
+
+ /// <summary>
+ /// Invoked when the application is launched normally by the end user. Other entry points
+ /// will be used when the application is launched to open a specific file, to display
+ /// search results, and so forth.
+ /// </summary>
+ /// <param name="args">Details about the launch request and process.</param>
+ protected override async void OnLaunched(LaunchActivatedEventArgs args)
+ {
+ Frame rootFrame = Window.Current.Content as Frame;
+
+ // Do not repeat app initialization when the Window already has content,
+ // just ensure that the window is active
+
+ if (rootFrame == null)
+ {
+ // Create a Frame to act as the navigation context and navigate to the first page
+ rootFrame = new Frame();
+ //Associate the frame with a SuspensionManager key
+ SuspensionManager.RegisterFrame(rootFrame, "AppFrame");
+
+ if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
+ {
+ // Restore the saved session state only when appropriate
+ try
+ {
+ await SuspensionManager.RestoreAsync();
+ }
+ catch (SuspensionManagerException)
+ {
+ //Something went wrong restoring state.
+ //Assume there is no state and continue
+ }
+ }
+
+ // Place the frame in the current Window
+ Window.Current.Content = rootFrame;
+ }
+ if (rootFrame.Content == null)
+ {
+ // When the navigation stack isn't restored navigate to the first page,
+ // configuring the new page by passing required information as a navigation
+ // parameter
+ if (!rootFrame.Navigate(typeof(GoodPerformancePage), "AllGroups"))
+ {
+ throw new Exception("Failed to create initial page");
+ }
+ }
+ // Ensure the current window is active
+ Window.Current.Activate();
+ }
+
+ /// <summary>
+ /// Invoked when application execution is being suspended. Application state is saved
+ /// without knowing whether the application will be terminated or resumed with the contents
+ /// of memory still intact.
+ /// </summary>
+ /// <param name="sender">The source of the suspend request.</param>
+ /// <param name="e">Details about the suspend request.</param>
+ private async void OnSuspending(object sender, SuspendingEventArgs e)
+ {
+ var deferral = e.SuspendingOperation.GetDeferral();
+ await SuspensionManager.SaveAsync();
+ deferral.Complete();
+ }
+ }
+}
BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/DarkGray.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/LightGray.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/Logo.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/MediumGray.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/SmallLogo.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/SplashScreen.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Assets/StoreLogo.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
76 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/BadPerformancePage.xaml
View
@@ -0,0 +1,76 @@
+<common:LayoutAwarePage
+ x:Name="pageRoot"
+ x:Class="WinRT_GridView_XAML_Performance_Problems.BadPerformancePage"
+ 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:common="using:WinRT_GridView_XAML_Performance_Problems.Common"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ NavigationCacheMode="Enabled"
+ mc:Ignorable="d">
+
+ <Page.Resources>
+ <CollectionViewSource
+ x:Name="groupedItemsViewSource"
+ Source="{Binding MoviesByYear}"
+ IsSourceGrouped="true"
+ ItemsPath="Movies"/>
+
+ </Page.Resources>
+
+ <Grid Style="{StaticResource LayoutRootStyle}">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="140"/>
+ <RowDefinition Height="*"/>
+ </Grid.RowDefinitions>
+
+ <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 MovieTemplate}"
+ 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">
+ <StackPanel Orientation="Horizontal">
+ <TextBlock Text="{Binding Name}" Margin="3,-7,10,10" Style="{StaticResource GroupHeaderTextStyle}" />
+ </StackPanel>
+ </Grid>
+ </DataTemplate>
+ </GroupStyle.HeaderTemplate>
+ <GroupStyle.Panel>
+ <ItemsPanelTemplate>
+ <VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"/>
+ </ItemsPanelTemplate>
+ </GroupStyle.Panel>
+ </GroupStyle>
+ </GridView.GroupStyle>
+ </GridView>
+
+ <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>
+
+ </Grid>
+</common:LayoutAwarePage>
35 ...T-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/BadPerformancePage.xaml.cs
View
@@ -0,0 +1,35 @@
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+// The Grouped Items Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234231
+
+namespace WinRT_GridView_XAML_Performance_Problems
+{
+ /// <summary>
+ /// A page that displays a grouped collection of items.
+ /// </summary>
+ public sealed partial class BadPerformancePage
+ {
+ private readonly MoviesVm viewModel = new MoviesVm();
+
+ public BadPerformancePage()
+ {
+ this.InitializeComponent();
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e)
+ {
+ if (e.NavigationMode == NavigationMode.Back)
+ return;
+
+ this.DataContext = viewModel;
+ this.viewModel.CreateBadPerformingData();
+ }
+
+ void ItemView_ItemClick(object sender, ItemClickEventArgs e)
+ {
+ this.Frame.Navigate(typeof(MovieDetailsPage));
+ }
+ }
+
+}
55 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/BindableBase.cs
View
@@ -0,0 +1,55 @@
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using Windows.UI.Xaml.Data;
+
+namespace WinRT_GridView_XAML_Performance_Problems.Common
+{
+ /// <summary>
+ /// Implementation of <see cref="INotifyPropertyChanged"/> to simplify models.
+ /// </summary>
+ [Windows.Foundation.Metadata.WebHostHidden]
+ public abstract class BindableBase : INotifyPropertyChanged
+ {
+ /// <summary>
+ /// Multicast event for property change notifications.
+ /// </summary>
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ /// <summary>
+ /// Checks if a property already matches a desired value. Sets the property and
+ /// notifies listeners only when necessary.
+ /// </summary>
+ /// <typeparam name="T">Type of the property.</typeparam>
+ /// <param name="storage">Reference to a property with both getter and setter.</param>
+ /// <param name="value">Desired value for the property.</param>
+ /// <param name="propertyName">Name of the property used to notify listeners. This
+ /// value is optional and can be provided automatically when invoked from compilers that
+ /// support CallerMemberName.</param>
+ /// <returns>True if the value was changed, false if the existing value matched the
+ /// desired value.</returns>
+ protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
+ {
+ if (object.Equals(storage, value)) return false;
+
+ storage = value;
+ this.OnPropertyChanged(propertyName);
+ return true;
+ }
+
+ /// <summary>
+ /// Notifies listeners that a property value has changed.
+ /// </summary>
+ /// <param name="propertyName">Name of the property used to notify listeners. This
+ /// value is optional and can be provided automatically when invoked from compilers
+ /// that support <see cref="CallerMemberNameAttribute"/>.</param>
+ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ var eventHandler = this.PropertyChanged;
+ if (eventHandler != null)
+ {
+ eventHandler(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
+}
21 ...ew-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/BooleanNegationConverter.cs
View
@@ -0,0 +1,21 @@
+using System;
+using Windows.UI.Xaml.Data;
+
+namespace WinRT_GridView_XAML_Performance_Problems.Common
+{
+ /// <summary>
+ /// Value converter that translates true to false and vice versa.
+ /// </summary>
+ public sealed class BooleanNegationConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, string language)
+ {
+ return !(value is bool && (bool)value);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, string language)
+ {
+ return !(value is bool && (bool)value);
+ }
+ }
+}
32 ...AML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/BooleanToVisibilityConverter.cs
View
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.Graphics.Display;
+using Windows.UI.ViewManagement;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Data;
+
+namespace WinRT_GridView_XAML_Performance_Problems.Common
+{
+ /// <summary>
+ /// Value converter that translates true to <see cref="Visibility.Visible"/> and false to
+ /// <see cref="Visibility.Collapsed"/>.
+ /// </summary>
+ public sealed class BooleanToVisibilityConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, string language)
+ {
+ return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, string language)
+ {
+ return value is Visibility && (Visibility)value == Visibility.Visible;
+ }
+ }
+}
464 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/LayoutAwarePage.cs
View
@@ -0,0 +1,464 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.System;
+using Windows.UI.Core;
+using Windows.UI.ViewManagement;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace WinRT_GridView_XAML_Performance_Problems.Common
+{
+ /// <summary>
+ /// Typical implementation of Page that provides several important conveniences:
+ /// <list type="bullet">
+ /// <item>
+ /// <description>Application view state to visual state mapping</description>
+ /// </item>
+ /// <item>
+ /// <description>GoBack, GoForward, and GoHome event handlers</description>
+ /// </item>
+ /// <item>
+ /// <description>Mouse and keyboard shortcuts for navigation</description>
+ /// </item>
+ /// <item>
+ /// <description>State management for navigation and process lifetime management</description>
+ /// </item>
+ /// <item>
+ /// <description>A default view model</description>
+ /// </item>
+ /// </list>
+ /// </summary>
+ [Windows.Foundation.Metadata.WebHostHidden]
+ public class LayoutAwarePage : Page
+ {
+ /// <summary>
+ /// Identifies the <see cref="DefaultViewModel"/> dependency property.
+ /// </summary>
+ public static readonly DependencyProperty DefaultViewModelProperty =
+ DependencyProperty.Register("DefaultViewModel", typeof(IObservableMap<String, Object>),
+ typeof(LayoutAwarePage), null);
+
+ private List<Control> _layoutAwareControls;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LayoutAwarePage"/> class.
+ /// </summary>
+ public LayoutAwarePage()
+ {
+ if (Windows.ApplicationModel.DesignMode.DesignModeEnabled) return;
+
+ // Create an empty default view model
+ this.DefaultViewModel = new ObservableDictionary<String, Object>();
+
+ // When this page is part of the visual tree make two changes:
+ // 1) Map application view state to visual state for the page
+ // 2) Handle keyboard and mouse navigation requests
+ this.Loaded += (sender, e) =>
+ {
+ this.StartLayoutUpdates(sender, e);
+
+ // Keyboard and mouse navigation only apply when occupying the entire window
+ if (this.ActualHeight == Window.Current.Bounds.Height &&
+ this.ActualWidth == Window.Current.Bounds.Width)
+ {
+ // Listen to the window directly so focus isn't required
+ Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated +=
+ CoreDispatcher_AcceleratorKeyActivated;
+ Window.Current.CoreWindow.PointerPressed +=
+ this.CoreWindow_PointerPressed;
+ }
+ };
+
+ // Undo the same changes when the page is no longer visible
+ this.Unloaded += (sender, e) =>
+ {
+ this.StopLayoutUpdates(sender, e);
+ Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated -=
+ CoreDispatcher_AcceleratorKeyActivated;
+ Window.Current.CoreWindow.PointerPressed -=
+ this.CoreWindow_PointerPressed;
+ };
+ }
+
+ /// <summary>
+ /// An implementation of <see cref="IObservableMap&lt;String, Object&gt;"/> designed to be
+ /// used as a trivial view model.
+ /// </summary>
+ protected IObservableMap<String, Object> DefaultViewModel
+ {
+ get
+ {
+ return this.GetValue(DefaultViewModelProperty) as IObservableMap<String, Object>;
+ }
+
+ set
+ {
+ this.SetValue(DefaultViewModelProperty, value);
+ }
+ }
+
+ #region Navigation support
+
+ /// <summary>
+ /// Invoked as an event handler to navigate backward in the page's associated
+ /// <see cref="Frame"/> until it reaches the top of the navigation stack.
+ /// </summary>
+ /// <param name="sender">Instance that triggered the event.</param>
+ /// <param name="e">Event data describing the conditions that led to the event.</param>
+ protected virtual void GoHome(object sender, RoutedEventArgs e)
+ {
+ // Use the navigation frame to return to the topmost page
+ if (this.Frame != null)
+ {
+ while (this.Frame.CanGoBack) this.Frame.GoBack();
+ }
+ }
+
+ /// <summary>
+ /// Invoked as an event handler to navigate backward in the navigation stack
+ /// associated with this page's <see cref="Frame"/>.
+ /// </summary>
+ /// <param name="sender">Instance that triggered the event.</param>
+ /// <param name="e">Event data describing the conditions that led to the
+ /// event.</param>
+ protected virtual void GoBack(object sender, RoutedEventArgs e)
+ {
+ // Use the navigation frame to return to the previous page
+ if (this.Frame != null && this.Frame.CanGoBack) this.Frame.GoBack();
+ }
+
+ /// <summary>
+ /// Invoked as an event handler to navigate forward in the navigation stack
+ /// associated with this page's <see cref="Frame"/>.
+ /// </summary>
+ /// <param name="sender">Instance that triggered the event.</param>
+ /// <param name="e">Event data describing the conditions that led to the
+ /// event.</param>
+ protected virtual void GoForward(object sender, RoutedEventArgs e)
+ {
+ // Use the navigation frame to move to the next page
+ if (this.Frame != null && this.Frame.CanGoForward) this.Frame.GoForward();
+ }
+
+ /// <summary>
+ /// Invoked on every keystroke, including system keys such as Alt key combinations, when
+ /// this page is active and occupies the entire window. Used to detect keyboard navigation
+ /// between pages even when the page itself doesn't have focus.
+ /// </summary>
+ /// <param name="sender">Instance that triggered the event.</param>
+ /// <param name="args">Event data describing the conditions that led to the event.</param>
+ private void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher sender,
+ AcceleratorKeyEventArgs args)
+ {
+ var virtualKey = args.VirtualKey;
+
+ // Only investigate further when Left, Right, or the dedicated Previous or Next keys
+ // are pressed
+ if ((args.EventType == CoreAcceleratorKeyEventType.SystemKeyDown ||
+ args.EventType == CoreAcceleratorKeyEventType.KeyDown) &&
+ (virtualKey == VirtualKey.Left || virtualKey == VirtualKey.Right ||
+ (int)virtualKey == 166 || (int)virtualKey == 167))
+ {
+ var coreWindow = Window.Current.CoreWindow;
+ var downState = CoreVirtualKeyStates.Down;
+ bool menuKey = (coreWindow.GetKeyState(VirtualKey.Menu) & downState) == downState;
+ bool controlKey = (coreWindow.GetKeyState(VirtualKey.Control) & downState) == downState;
+ bool shiftKey = (coreWindow.GetKeyState(VirtualKey.Shift) & downState) == downState;
+ bool noModifiers = !menuKey && !controlKey && !shiftKey;
+ bool onlyAlt = menuKey && !controlKey && !shiftKey;
+
+ if (((int)virtualKey == 166 && noModifiers) ||
+ (virtualKey == VirtualKey.Left && onlyAlt))
+ {
+ // When the previous key or Alt+Left are pressed navigate back
+ args.Handled = true;
+ this.GoBack(this, new RoutedEventArgs());
+ }
+ else if (((int)virtualKey == 167 && noModifiers) ||
+ (virtualKey == VirtualKey.Right && onlyAlt))
+ {
+ // When the next key or Alt+Right are pressed navigate forward
+ args.Handled = true;
+ this.GoForward(this, new RoutedEventArgs());
+ }
+ }
+ }
+
+ /// <summary>
+ /// Invoked on every mouse click, touch screen tap, or equivalent interaction when this
+ /// page is active and occupies the entire window. Used to detect browser-style next and
+ /// previous mouse button clicks to navigate between pages.
+ /// </summary>
+ /// <param name="sender">Instance that triggered the event.</param>
+ /// <param name="args">Event data describing the conditions that led to the event.</param>
+ private void CoreWindow_PointerPressed(CoreWindow sender,
+ PointerEventArgs args)
+ {
+ var properties = args.CurrentPoint.Properties;
+
+ // Ignore button chords with the left, right, and middle buttons
+ if (properties.IsLeftButtonPressed || properties.IsRightButtonPressed ||
+ properties.IsMiddleButtonPressed) return;
+
+ // If back or foward are pressed (but not both) navigate appropriately
+ bool backPressed = properties.IsXButton1Pressed;
+ bool forwardPressed = properties.IsXButton2Pressed;
+ if (backPressed ^ forwardPressed)
+ {
+ args.Handled = true;
+ if (backPressed) this.GoBack(this, new RoutedEventArgs());
+ if (forwardPressed) this.GoForward(this, new RoutedEventArgs());
+ }
+ }
+
+ #endregion
+
+ #region Visual state switching
+
+ /// <summary>
+ /// Invoked as an event handler, typically on the <see cref="FrameworkElement.Loaded"/>
+ /// event of a <see cref="Control"/> within the page, to indicate that the sender should
+ /// start receiving visual state management changes that correspond to application view
+ /// state changes.
+ /// </summary>
+ /// <param name="sender">Instance of <see cref="Control"/> that supports visual state
+ /// management corresponding to view states.</param>
+ /// <param name="e">Event data that describes how the request was made.</param>
+ /// <remarks>The current view state will immediately be used to set the corresponding
+ /// visual state when layout updates are requested. A corresponding
+ /// <see cref="FrameworkElement.Unloaded"/> event handler connected to
+ /// <see cref="StopLayoutUpdates"/> is strongly encouraged. Instances of
+ /// <see cref="LayoutAwarePage"/> automatically invoke these handlers in their Loaded and
+ /// Unloaded events.</remarks>
+ /// <seealso cref="DetermineVisualState"/>
+ /// <seealso cref="InvalidateVisualState"/>
+ public void StartLayoutUpdates(object sender, RoutedEventArgs e)
+ {
+ var control = sender as Control;
+ if (control == null) return;
+ if (this._layoutAwareControls == null)
+ {
+ // Start listening to view state changes when there are controls interested in updates
+ Window.Current.SizeChanged += this.WindowSizeChanged;
+ this._layoutAwareControls = new List<Control>();
+ }
+ this._layoutAwareControls.Add(control);
+
+ // Set the initial visual state of the control
+ VisualStateManager.GoToState(control, DetermineVisualState(ApplicationView.Value), false);
+ }
+
+ private void WindowSizeChanged(object sender, WindowSizeChangedEventArgs e)
+ {
+ this.InvalidateVisualState();
+ }
+
+ /// <summary>
+ /// Invoked as an event handler, typically on the <see cref="FrameworkElement.Unloaded"/>
+ /// event of a <see cref="Control"/>, to indicate that the sender should start receiving
+ /// visual state management changes that correspond to application view state changes.
+ /// </summary>
+ /// <param name="sender">Instance of <see cref="Control"/> that supports visual state
+ /// management corresponding to view states.</param>
+ /// <param name="e">Event data that describes how the request was made.</param>
+ /// <remarks>The current view state will immediately be used to set the corresponding
+ /// visual state when layout updates are requested.</remarks>
+ /// <seealso cref="StartLayoutUpdates"/>
+ public void StopLayoutUpdates(object sender, RoutedEventArgs e)
+ {
+ var control = sender as Control;
+ if (control == null || this._layoutAwareControls == null) return;
+ this._layoutAwareControls.Remove(control);
+ if (this._layoutAwareControls.Count == 0)
+ {
+ // Stop listening to view state changes when no controls are interested in updates
+ this._layoutAwareControls = null;
+ Window.Current.SizeChanged -= this.WindowSizeChanged;
+ }
+ }
+
+ /// <summary>
+ /// Translates <see cref="ApplicationViewState"/> values into strings for visual state
+ /// management within the page. The default implementation uses the names of enum values.
+ /// Subclasses may override this method to control the mapping scheme used.
+ /// </summary>
+ /// <param name="viewState">View state for which a visual state is desired.</param>
+ /// <returns>Visual state name used to drive the
+ /// <see cref="VisualStateManager"/></returns>
+ /// <seealso cref="InvalidateVisualState"/>
+ protected virtual string DetermineVisualState(ApplicationViewState viewState)
+ {
+ return viewState.ToString();
+ }
+
+ /// <summary>
+ /// Updates all controls that are listening for visual state changes with the correct
+ /// visual state.
+ /// </summary>
+ /// <remarks>
+ /// Typically used in conjunction with overriding <see cref="DetermineVisualState"/> to
+ /// signal that a different value may be returned even though the view state has not
+ /// changed.
+ /// </remarks>
+ public void InvalidateVisualState()
+ {
+ if (this._layoutAwareControls != null)
+ {
+ string visualState = DetermineVisualState(ApplicationView.Value);
+ foreach (var layoutAwareControl in this._layoutAwareControls)
+ {
+ VisualStateManager.GoToState(layoutAwareControl, visualState, false);
+ }
+ }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Implementation of IObservableMap that supports reentrancy for use as a default view
+ /// model.
+ /// </summary>
+ private class ObservableDictionary<K, V> : IObservableMap<K, V>
+ {
+ private class ObservableDictionaryChangedEventArgs : IMapChangedEventArgs<K>
+ {
+ public ObservableDictionaryChangedEventArgs(CollectionChange change, K key)
+ {
+ this.CollectionChange = change;
+ this.Key = key;
+ }
+
+ public CollectionChange CollectionChange { get; private set; }
+ public K Key { get; private set; }
+ }
+
+ private Dictionary<K, V> _dictionary = new Dictionary<K, V>();
+ public event MapChangedEventHandler<K, V> MapChanged;
+
+ private void InvokeMapChanged(CollectionChange change, K key)
+ {
+ var eventHandler = MapChanged;
+ if (eventHandler != null)
+ {
+ eventHandler(this, new ObservableDictionaryChangedEventArgs(change, key));
+ }
+ }
+
+ public void Add(K key, V value)
+ {
+ this._dictionary.Add(key, value);
+ this.InvokeMapChanged(CollectionChange.ItemInserted, key);
+ }
+
+ public void Add(KeyValuePair<K, V> item)
+ {
+ this.Add(item.Key, item.Value);
+ }
+
+ public bool Remove(K key)
+ {
+ if (this._dictionary.Remove(key))
+ {
+ this.InvokeMapChanged(CollectionChange.ItemRemoved, key);
+ return true;
+ }
+ return false;
+ }
+
+ public bool Remove(KeyValuePair<K, V> item)
+ {
+ V currentValue;
+ if (this._dictionary.TryGetValue(item.Key, out currentValue) &&
+ Object.Equals(item.Value, currentValue) && this._dictionary.Remove(item.Key))
+ {
+ this.InvokeMapChanged(CollectionChange.ItemRemoved, item.Key);
+ return true;
+ }
+ return false;
+ }
+
+ public V this[K key]
+ {
+ get
+ {
+ return this._dictionary[key];
+ }
+ set
+ {
+ this._dictionary[key] = value;
+ this.InvokeMapChanged(CollectionChange.ItemChanged, key);
+ }
+ }
+
+ public void Clear()
+ {
+ var priorKeys = this._dictionary.Keys.ToArray();
+ this._dictionary.Clear();
+ foreach (var key in priorKeys)
+ {
+ this.InvokeMapChanged(CollectionChange.ItemRemoved, key);
+ }
+ }
+
+ public ICollection<K> Keys
+ {
+ get { return this._dictionary.Keys; }
+ }
+
+ public bool ContainsKey(K key)
+ {
+ return this._dictionary.ContainsKey(key);
+ }
+
+ public bool TryGetValue(K key, out V value)
+ {
+ return this._dictionary.TryGetValue(key, out value);
+ }
+
+ public ICollection<V> Values
+ {
+ get { return this._dictionary.Values; }
+ }
+
+ public bool Contains(KeyValuePair<K, V> item)
+ {
+ return this._dictionary.Contains(item);
+ }
+
+ public int Count
+ {
+ get { return this._dictionary.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return false; }
+ }
+
+ public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
+ {
+ return this._dictionary.GetEnumerator();
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return this._dictionary.GetEnumerator();
+ }
+
+ public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
+ {
+ int arraySize = array.Length;
+ foreach (var pair in this._dictionary)
+ {
+ if (arrayIndex >= arraySize) break;
+ array[arrayIndex++] = pair;
+ }
+ }
+ }
+ }
+}
12 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/ReadMe.txt
View
@@ -0,0 +1,12 @@
+The Common directory contains classes and XAML styles that simplify application development.
+
+These are not merely convenient, but are required by most Visual Studio project and item templates.
+If you need a variation on one of the styles in StandardStyles it is recommended that you make a
+copy in your own resource dictionary. When right-clicking on a styled control in the design
+surface the context menu includes an option to Edit a Copy to simplify this process.
+
+Classes in the Common directory form part of your project and may be further enhanced to meet your
+needs. Care should be taken when altering existing methods and properties as incompatible changes
+will require corresponding changes to code included in a variety of Visual Studio templates. For
+example, additional pages added to your project are written assuming that the original methods and
+properties in Common classes are still present and that the names of the types have not changed.
210 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/RichTextColumns.cs
View
@@ -0,0 +1,210 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Windows.Foundation;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Documents;
+
+namespace WinRT_GridView_XAML_Performance_Problems.Common
+{
+ /// <summary>
+ /// Wrapper for <see cref="RichTextBlock"/> that creates as many additional overflow
+ /// columns as needed to fit the available content.
+ /// </summary>
+ /// <example>
+ /// The following creates a collection of 400-pixel wide columns spaced 50 pixels apart
+ /// to contain arbitrary data-bound content:
+ /// <code>
+ /// <RichTextColumns>
+ /// <RichTextColumns.ColumnTemplate>
+ /// <DataTemplate>
+ /// <RichTextBlockOverflow Width="400" Margin="50,0,0,0"/>
+ /// </DataTemplate>
+ /// </RichTextColumns.ColumnTemplate>
+ ///
+ /// <RichTextBlock Width="400">
+ /// <Paragraph>
+ /// <Run Text="{Binding Content}"/>
+ /// </Paragraph>
+ /// </RichTextBlock>
+ /// </RichTextColumns>
+ /// </code>
+ /// </example>
+ /// <remarks>Typically used in a horizontally scrolling region where an unbounded amount of
+ /// space allows for all needed columns to be created. When used in a vertically scrolling
+ /// space there will never be any additional columns.</remarks>
+ [Windows.UI.Xaml.Markup.ContentProperty(Name = "RichTextContent")]
+ public sealed class RichTextColumns : Panel
+ {
+ /// <summary>
+ /// Identifies the <see cref="RichTextContent"/> dependency property.
+ /// </summary>
+ public static readonly DependencyProperty RichTextContentProperty =
+ DependencyProperty.Register("RichTextContent", typeof(RichTextBlock),
+ typeof(RichTextColumns), new PropertyMetadata(null, ResetOverflowLayout));
+
+ /// <summary>
+ /// Identifies the <see cref="ColumnTemplate"/> dependency property.
+ /// </summary>
+ public static readonly DependencyProperty ColumnTemplateProperty =
+ DependencyProperty.Register("ColumnTemplate", typeof(DataTemplate),
+ typeof(RichTextColumns), new PropertyMetadata(null, ResetOverflowLayout));
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RichTextColumns"/> class.
+ /// </summary>
+ public RichTextColumns()
+ {
+ this.HorizontalAlignment = HorizontalAlignment.Left;
+ }
+
+ /// <summary>
+ /// Gets or sets the initial rich text content to be used as the first column.
+ /// </summary>
+ public RichTextBlock RichTextContent
+ {
+ get { return (RichTextBlock)GetValue(RichTextContentProperty); }
+ set { SetValue(RichTextContentProperty, value); }
+ }
+
+ /// <summary>
+ /// Gets or sets the template used to create additional
+ /// <see cref="RichTextBlockOverflow"/> instances.
+ /// </summary>
+ public DataTemplate ColumnTemplate
+ {
+ get { return (DataTemplate)GetValue(ColumnTemplateProperty); }
+ set { SetValue(ColumnTemplateProperty, value); }
+ }
+
+ /// <summary>
+ /// Invoked when the content or overflow template is changed to recreate the column layout.
+ /// </summary>
+ /// <param name="d">Instance of <see cref="RichTextColumns"/> where the change
+ /// occurred.</param>
+ /// <param name="e">Event data describing the specific change.</param>
+ private static void ResetOverflowLayout(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ // When dramatic changes occur, rebuild the column layout from scratch
+ var target = d as RichTextColumns;
+ if (target != null)
+ {
+ target._overflowColumns = null;
+ target.Children.Clear();
+ target.InvalidateMeasure();
+ }
+ }
+
+ /// <summary>
+ /// Lists overflow columns already created. Must maintain a 1:1 relationship with
+ /// instances in the <see cref="Panel.Children"/> collection following the initial
+ /// RichTextBlock child.
+ /// </summary>
+ private List<RichTextBlockOverflow> _overflowColumns = null;
+
+ /// <summary>
+ /// Determines whether additional overflow columns are needed and if existing columns can
+ /// be removed.
+ /// </summary>
+ /// <param name="availableSize">The size of the space available, used to constrain the
+ /// number of additional columns that can be created.</param>
+ /// <returns>The resulting size of the original content plus any extra columns.</returns>
+ protected override Size MeasureOverride(Size availableSize)
+ {
+ if (this.RichTextContent == null) return new Size(0, 0);
+
+ // Make sure the RichTextBlock is a child, using the lack of
+ // a list of additional columns as a sign that this hasn't been
+ // done yet
+ if (this._overflowColumns == null)
+ {
+ Children.Add(this.RichTextContent);
+ this._overflowColumns = new List<RichTextBlockOverflow>();
+ }
+
+ // Start by measuring the original RichTextBlock content
+ this.RichTextContent.Measure(availableSize);
+ var maxWidth = this.RichTextContent.DesiredSize.Width;
+ var maxHeight = this.RichTextContent.DesiredSize.Height;
+ var hasOverflow = this.RichTextContent.HasOverflowContent;
+
+ // Make sure there are enough overflow columns
+ int overflowIndex = 0;
+ while (hasOverflow && maxWidth < availableSize.Width && this.ColumnTemplate != null)
+ {
+ // Use existing overflow columns until we run out, then create
+ // more from the supplied template
+ RichTextBlockOverflow overflow;
+ if (this._overflowColumns.Count > overflowIndex)
+ {
+ overflow = this._overflowColumns[overflowIndex];
+ }
+ else
+ {
+ overflow = (RichTextBlockOverflow)this.ColumnTemplate.LoadContent();
+ this._overflowColumns.Add(overflow);
+ this.Children.Add(overflow);
+ if (overflowIndex == 0)
+ {
+ this.RichTextContent.OverflowContentTarget = overflow;
+ }
+ else
+ {
+ this._overflowColumns[overflowIndex - 1].OverflowContentTarget = overflow;
+ }
+ }
+
+ // Measure the new column and prepare to repeat as necessary
+ overflow.Measure(new Size(availableSize.Width - maxWidth, availableSize.Height));
+ maxWidth += overflow.DesiredSize.Width;
+ maxHeight = Math.Max(maxHeight, overflow.DesiredSize.Height);
+ hasOverflow = overflow.HasOverflowContent;
+ overflowIndex++;
+ }
+
+ // Disconnect extra columns from the overflow chain, remove them from our private list
+ // of columns, and remove them as children
+ if (this._overflowColumns.Count > overflowIndex)
+ {
+ if (overflowIndex == 0)
+ {
+ this.RichTextContent.OverflowContentTarget = null;
+ }
+ else
+ {
+ this._overflowColumns[overflowIndex - 1].OverflowContentTarget = null;
+ }
+ while (this._overflowColumns.Count > overflowIndex)
+ {
+ this._overflowColumns.RemoveAt(overflowIndex);
+ this.Children.RemoveAt(overflowIndex + 1);
+ }
+ }
+
+ // Report final determined size
+ return new Size(maxWidth, maxHeight);
+ }
+
+ /// <summary>
+ /// Arranges the original content and all extra columns.
+ /// </summary>
+ /// <param name="finalSize">Defines the size of the area the children must be arranged
+ /// within.</param>
+ /// <returns>The size of the area the children actually required.</returns>
+ protected override Size ArrangeOverride(Size finalSize)
+ {
+ double maxWidth = 0;
+ double maxHeight = 0;
+ foreach (var child in Children)
+ {
+ child.Arrange(new Rect(maxWidth, 0, child.DesiredSize.Width, finalSize.Height));
+ maxWidth += child.DesiredSize.Width;
+ maxHeight = Math.Max(maxHeight, child.DesiredSize.Height);
+ }
+ return new Size(maxWidth, maxHeight);
+ }
+ }
+}
1,829 ...T-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/StandardStyles.xaml
View
1,829 additions, 0 deletions not shown
257 ...-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Common/SuspensionManager.cs
View
@@ -0,0 +1,257 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+using Windows.ApplicationModel;
+using Windows.Storage;
+using Windows.Storage.Streams;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace WinRT_GridView_XAML_Performance_Problems.Common
+{
+ /// <summary>
+ /// SuspensionManager captures global session state to simplify process lifetime management
+ /// for an application. Note that session state will be automatically cleared under a variety
+ /// of conditions and should only be used to store information that would be convenient to
+ /// carry across sessions, but that should be discarded when an application crashes or is
+ /// upgraded.
+ /// </summary>
+ internal sealed class SuspensionManager
+ {
+ private static Dictionary<string, object> _sessionState = new Dictionary<string, object>();
+ private static List<Type> _knownTypes = new List<Type>();
+ private const string sessionStateFilename = "_sessionState.xml";
+
+ /// <summary>
+ /// Provides access to global session state for the current session. This state is
+ /// serialized by <see cref="SaveAsync"/> and restored by
+ /// <see cref="RestoreAsync"/>, so values must be serializable by
+ /// <see cref="DataContractSerializer"/> and should be as compact as possible. Strings
+ /// and other self-contained data types are strongly recommended.
+ /// </summary>
+ public static Dictionary<string, object> SessionState
+ {
+ get { return _sessionState; }
+ }
+
+ /// <summary>
+ /// List of custom types provided to the <see cref="DataContractSerializer"/> when
+ /// reading and writing session state. Initially empty, additional types may be
+ /// added to customize the serialization process.
+ /// </summary>
+ public static List<Type> KnownTypes
+ {
+ get { return _knownTypes; }
+ }
+
+ /// <summary>
+ /// Save the current <see cref="SessionState"/>. Any <see cref="Frame"/> instances
+ /// registered with <see cref="RegisterFrame"/> will also preserve their current
+ /// navigation stack, which in turn gives their active <see cref="Page"/> an opportunity
+ /// to save its state.
+ /// </summary>
+ /// <returns>An asynchronous task that reflects when session state has been saved.</returns>
+ public static async Task SaveAsync()
+ {
+ try
+ {
+ // Save the navigation state for all registered frames
+ foreach (var weakFrameReference in _registeredFrames)
+ {
+ Frame frame;
+ if (weakFrameReference.TryGetTarget(out frame))
+ {
+ SaveFrameNavigationState(frame);
+ }
+ }
+
+ // Serialize the session state synchronously to avoid asynchronous access to shared
+ // state
+ MemoryStream sessionData = new MemoryStream();
+ DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
+ serializer.WriteObject(sessionData, _sessionState);
+
+ // Get an output stream for the SessionState file and write the state asynchronously
+ StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(sessionStateFilename, CreationCollisionOption.ReplaceExisting);
+ using (Stream fileStream = await file.OpenStreamForWriteAsync())
+ {
+ sessionData.Seek(0, SeekOrigin.Begin);
+ await sessionData.CopyToAsync(fileStream);
+ await fileStream.FlushAsync();
+ }
+ }
+ catch (Exception e)
+ {
+ throw new SuspensionManagerException(e);
+ }
+ }
+
+ /// <summary>
+ /// Restores previously saved <see cref="SessionState"/>. Any <see cref="Frame"/> instances
+ /// registered with <see cref="RegisterFrame"/> will also restore their prior navigation
+ /// state, which in turn gives their active <see cref="Page"/> an opportunity restore its
+ /// state.
+ /// </summary>
+ /// <returns>An asynchronous task that reflects when session state has been read. The
+ /// content of <see cref="SessionState"/> should not be relied upon until this task
+ /// completes.</returns>
+ public static async Task RestoreAsync()
+ {
+ _sessionState = new Dictionary<String, Object>();
+
+ try
+ {
+ // Get the input stream for the SessionState file
+ StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(sessionStateFilename);
+ using (IInputStream inStream = await file.OpenSequentialReadAsync())
+ {
+ // Deserialize the Session State
+ DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
+ _sessionState = (Dictionary<string, object>)serializer.ReadObject(inStream.AsStreamForRead());
+ }
+
+ // Restore any registered frames to their saved state
+ foreach (var weakFrameReference in _registeredFrames)
+ {
+ Frame frame;
+ if (weakFrameReference.TryGetTarget(out frame))
+ {
+ frame.ClearValue(FrameSessionStateProperty);
+ RestoreFrameNavigationState(frame);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new SuspensionManagerException(e);
+ }
+ }
+
+ private static DependencyProperty FrameSessionStateKeyProperty =
+ DependencyProperty.RegisterAttached("_FrameSessionStateKey", typeof(String), typeof(SuspensionManager), null);
+ private static DependencyProperty FrameSessionStateProperty =
+ DependencyProperty.RegisterAttached("_FrameSessionState", typeof(Dictionary<String, Object>), typeof(SuspensionManager), null);
+ private static List<WeakReference<Frame>> _registeredFrames = new List<WeakReference<Frame>>();
+
+ /// <summary>
+ /// Registers a <see cref="Frame"/> instance to allow its navigation history to be saved to
+ /// and restored from <see cref="SessionState"/>. Frames should be registered once
+ /// immediately after creation if they will participate in session state management. Upon
+ /// registration if state has already been restored for the specified key
+ /// the navigation history will immediately be restored. Subsequent invocations of
+ /// <see cref="RestoreAsync"/> will also restore navigation history.
+ /// </summary>
+ /// <param name="frame">An instance whose navigation history should be managed by
+ /// <see cref="SuspensionManager"/></param>
+ /// <param name="sessionStateKey">A unique key into <see cref="SessionState"/> used to
+ /// store navigation-related information.</param>
+ public static void RegisterFrame(Frame frame, String sessionStateKey)
+ {
+ if (frame.GetValue(FrameSessionStateKeyProperty) != null)
+ {
+ throw new InvalidOperationException("Frames can only be registered to one session state key");
+ }
+
+ if (frame.GetValue(FrameSessionStateProperty) != null)
+ {
+ throw new InvalidOperationException("Frames must be either be registered before accessing frame session state, or not registered at all");
+ }
+
+ // Use a dependency property to associate the session key with a frame, and keep a list of frames whose
+ // navigation state should be managed
+ frame.SetValue(FrameSessionStateKeyProperty, sessionStateKey);
+ _registeredFrames.Add(new WeakReference<Frame>(frame));
+
+ // Check to see if navigation state can be restored
+ RestoreFrameNavigationState(frame);
+ }
+
+ /// <summary>
+ /// Disassociates a <see cref="Frame"/> previously registered by <see cref="RegisterFrame"/>
+ /// from <see cref="SessionState"/>. Any navigation state previously captured will be
+ /// removed.
+ /// </summary>
+ /// <param name="frame">An instance whose navigation history should no longer be
+ /// managed.</param>
+ public static void UnregisterFrame(Frame frame)
+ {
+ // Remove session state and remove the frame from the list of frames whose navigation
+ // state will be saved (along with any weak references that are no longer reachable)
+ SessionState.Remove((String)frame.GetValue(FrameSessionStateKeyProperty));
+ _registeredFrames.RemoveAll((weakFrameReference) =>
+ {
+ Frame testFrame;
+ return !weakFrameReference.TryGetTarget(out testFrame) || testFrame == frame;
+ });
+ }
+
+ /// <summary>
+ /// Provides storage for session state associated with the specified <see cref="Frame"/>.
+ /// Frames that have been previously registered with <see cref="RegisterFrame"/> have
+ /// their session state saved and restored automatically as a part of the global
+ /// <see cref="SessionState"/>. Frames that are not registered have transient state
+ /// that can still be useful when restoring pages that have been discarded from the
+ /// navigation cache.
+ /// </summary>
+ /// <remarks>Apps may choose to rely on <see cref="LayoutAwarePage"/> to manage
+ /// page-specific state instead of working with frame session state directly.</remarks>
+ /// <param name="frame">The instance for which session state is desired.</param>
+ /// <returns>A collection of state subject to the same serialization mechanism as
+ /// <see cref="SessionState"/>.</returns>
+ public static Dictionary<String, Object> SessionStateForFrame(Frame frame)
+ {
+ var frameState = (Dictionary<String, Object>)frame.GetValue(FrameSessionStateProperty);
+
+ if (frameState == null)
+ {
+ var frameSessionKey = (String)frame.GetValue(FrameSessionStateKeyProperty);
+ if (frameSessionKey != null)
+ {
+ // Registered frames reflect the corresponding session state
+ if (!_sessionState.ContainsKey(frameSessionKey))
+ {
+ _sessionState[frameSessionKey] = new Dictionary<String, Object>();
+ }
+ frameState = (Dictionary<String, Object>)_sessionState[frameSessionKey];
+ }
+ else
+ {
+ // Frames that aren't registered have transient state
+ frameState = new Dictionary<String, Object>();
+ }
+ frame.SetValue(FrameSessionStateProperty, frameState);
+ }
+ return frameState;
+ }
+
+ private static void RestoreFrameNavigationState(Frame frame)
+ {
+ var frameState = SessionStateForFrame(frame);
+ if (frameState.ContainsKey("Navigation"))
+ {
+ frame.SetNavigationState((String)frameState["Navigation"]);
+ }
+ }
+
+ private static void SaveFrameNavigationState(Frame frame)
+ {
+ var frameState = SessionStateForFrame(frame);
+ frameState["Navigation"] = frame.GetNavigationState();
+ }
+ }
+ public class SuspensionManagerException : Exception
+ {
+ public SuspensionManagerException()
+ {
+ }
+
+ public SuspensionManagerException(Exception e) : base("SuspensionManager failed", e)
+ {
+
+ }
+ }
+}
74 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Data/VideoService.cs
View
@@ -0,0 +1,74 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Json;
+using System.Threading.Tasks;
+
+namespace WinRT_GridView_XAML_Performance_Problems.Data
+{
+ public class MovieService
+ {
+ private const string Uri = @"https://api.elisaviihde.fi/etvrecorder/vod.sl?data=true&category=popular&count=125";
+
+ public async Task<List<MovieInfo>> GetMovies()
+ {
+ var client = new HttpClient();
+
+ var jsonStream = await client.GetStreamAsync(Uri);
+ var serializer = new DataContractJsonSerializer(typeof(MovieInfoCollectionDto));
+
+ var collection = (MovieInfoCollectionDto)serializer.ReadObject(jsonStream);
+
+ var result = collection.vods.Select(x => x).ToList();
+ return result;
+ }
+ }
+
+ [DataContract]
+ public class MovieInfoCollectionDto
+ {
+ [DataMember]
+ public List<MovieInfo> vods;
+ }
+
+ [DataContract]
+ public class MovieInfo
+ {
+ [DataMember]
+ private string title;
+ [DataMember]
+ private long id;
+ [DataMember]
+ private int length;
+ [DataMember]
+ private string agelimit;
+ [DataMember]
+ private int year;
+ [DataMember]
+ private int price;
+ [DataMember]
+ private string currency;
+ [DataMember]
+ private string trailer_url;
+ [DataMember]
+ private string cover;
+ [DataMember]
+ private string categoryid;
+
+ public string Title
+ {
+ get { return title; }
+ }
+
+ public int Year
+ {
+ get { return year; }
+ }
+
+ public string Cover
+ {
+ get { return cover; }
+ }
+ }
+}
82 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/GoodPerformancePage.xaml
View
@@ -0,0 +1,82 @@
+<common:LayoutAwarePage
+ x:Name="pageRoot"
+ x:Class="WinRT_GridView_XAML_Performance_Problems.GoodPerformancePage"
+ 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:WinRT_GridView_XAML_Performance_Problems"
+ xmlns:common="using:WinRT_GridView_XAML_Performance_Problems.Common"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ NavigationCacheMode="Enabled"
+ mc:Ignorable="d">
+
+ <Page.Resources>
+ <local:MyTemplateSelector x:Key="MyTemplateSelector"/>
+ </Page.Resources>
+
+ <Grid Style="{StaticResource LayoutRootStyle}">
+ <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" Grid.Column="1" Text="{StaticResource AppName}" Style="{StaticResource PageHeaderTextStyle}"/>
+ </Grid>
+
+ <SemanticZoom Grid.Row="1" ViewChangeStarted="SemanticZoom_OnViewChangeStarted" x:Name="Zoom"
+ ViewChangeCompleted="SemanticZoom_OnViewChangeCompleted">
+ <SemanticZoom.ZoomedInView>
+ <GridView x:Name="itemGridView"
+ TabIndex="1"
+ Padding="116,15,40,46"
+ ItemsSource="{Binding Items}"
+ ItemTemplateSelector="{StaticResource MyTemplateSelector}"
+ SelectionMode="None"
+ IsSwipeEnabled="false" IsItemClickEnabled="True"
+ ItemClick="ItemView_ItemClick">
+ </GridView>
+ </SemanticZoom.ZoomedInView>
+ <SemanticZoom.ZoomedOutView>
+ <GridView VerticalAlignment="Center" Margin="200,-100,0,0" x:Name="ZoomedOutGrid" ItemsSource="{Binding Groups}"
+ SelectionMode="None">
+ <GridView.ItemTemplate>
+ <DataTemplate>
+ <StackPanel >
+ <TextBlock HorizontalAlignment="Center"
+ Text="{Binding}"
+ Style="{StaticResource SubheaderTextStyle}"
+ />
+ </StackPanel>
+ </DataTemplate>
+ </GridView.ItemTemplate>
+
+ <GridView.ItemContainerStyle>
+ <Style TargetType="GridViewItem">
+ <Setter Property="Margin" Value="4" />
+ <Setter Property="Padding" Value="5" />
+ <Setter Property="HorizontalContentAlignment" Value="Left" />
+ <Setter Property="VerticalContentAlignment" Value="Center" />
+ </Style>
+ </GridView.ItemContainerStyle>
+
+ <GridView.ItemsPanel>
+ <ItemsPanelTemplate>
+ <WrapGrid ItemWidth="400" ItemHeight="70"
+ Orientation="Horizontal" VerticalChildrenAlignment="Center" MaximumRowsOrColumns="3"></WrapGrid>
+ </ItemsPanelTemplate>
+ </GridView.ItemsPanel>
+ </GridView>
+ </SemanticZoom.ZoomedOutView>
+
+ </SemanticZoom>
+
+ </Grid>
+</common:LayoutAwarePage>
59 ...-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/GoodPerformancePage.xaml.cs
View
@@ -0,0 +1,59 @@
+using WinRT_GridView_XAML_Performance_Problems.Data;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace WinRT_GridView_XAML_Performance_Problems
+{
+ public sealed partial class GoodPerformancePage
+ {
+ private readonly MoviesVm viewModel = new MoviesVm();
+ public GoodPerformancePage()
+ {
+ this.InitializeComponent();
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e)
+ {
+ if (e.NavigationMode == NavigationMode.Back)
+ return;
+
+ this.DataContext = viewModel;
+ this.viewModel.CreateDataWithGreatPerformance();
+ }
+
+ void ItemView_ItemClick(object sender, ItemClickEventArgs e)
+ {
+ if (e.ClickedItem is MovieInfo)
+ this.Frame.Navigate(typeof (MovieDetailsPage));
+ else
+ this.Zoom.IsZoomedInViewActive = false;
+ }
+
+ private void SemanticZoom_OnViewChangeStarted(object sender, SemanticZoomViewChangedEventArgs e)
+ {
+ if (e.IsSourceZoomedInView)
+ return;
+
+ this.itemGridView.Opacity = 0;
+ }
+
+ private void SemanticZoom_OnViewChangeCompleted(object sender, SemanticZoomViewChangedEventArgs e)
+ {
+ if (e.IsSourceZoomedInView)
+ return;
+
+ try
+ {
+ var selectedGroup = e.SourceItem.Item as string;
+ if (selectedGroup == null)
+ return;
+
+ itemGridView.ScrollIntoView(selectedGroup, ScrollIntoViewAlignment.Leading);
+ }
+ finally
+ {
+ this.itemGridView.Opacity = 1;
+ }
+ }
+ }
+}
40 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/MovieDetailsPage.xaml
View
@@ -0,0 +1,40 @@
+<common:LayoutAwarePage
+ x:Name="pageRoot"
+ x:Class="WinRT_GridView_XAML_Performance_Problems.MovieDetailsPage"
+ 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:WinRT_GridView_XAML_Performance_Problems"
+ xmlns:data="using:WinRT_GridView_XAML_Performance_Problems.Data"
+ xmlns:common="using:WinRT_GridView_XAML_Performance_Problems.Common"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d">
+
+ <!--
+ 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>
+
+ <TextBlock Grid.Row="1" Margin="120 0 0 0" Style="{StaticResource SubheaderTextStyle}">This page would show movie details</TextBlock>
+
+ <!-- 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="Placeholder for Movie Details" Style="{StaticResource PageHeaderTextStyle}" Grid.Column="1" IsHitTestVisible="false"/>
+ </Grid>
+
+ </Grid>
+</common:LayoutAwarePage>
32 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/MovieDetailsPage.xaml.cs
View
@@ -0,0 +1,32 @@
+using WinRT_GridView_XAML_Performance_Problems.Data;
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+// The Item Detail Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234232
+
+namespace WinRT_GridView_XAML_Performance_Problems
+{
+ /// <summary>
+ /// A page that displays details for a single item within a group while allowing gestures to
+ /// flip through other items belonging to the same group.
+ /// </summary>
+ public sealed partial class MovieDetailsPage : WinRT_GridView_XAML_Performance_Problems.Common.LayoutAwarePage
+ {
+ public MovieDetailsPage()
+ {
+ this.InitializeComponent();
+ }
+ }
+}
88 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/MoviesVm.cs
View
@@ -0,0 +1,88 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Threading.Tasks;
+using WinRT_GridView_XAML_Performance_Problems.Data;
+
+namespace WinRT_GridView_XAML_Performance_Problems
+{
+ public class MoviesVm
+ {
+ /// <summary>
+ /// This is used when the grouping is enabled. It will give a horrible performance
+ /// </summary>
+ public ObservableCollection<Category> MoviesByYear { get; set; }
+
+ /// <summary>
+ /// These two are used when the grouping is done manually
+ /// </summary>
+ public ObservableCollection<object> Items { get; set; }
+ public ObservableCollection<string> Groups { get; set; }
+
+ public MoviesVm()
+ {
+ this.MoviesByYear = new ObservableCollection<Category>();
+ this.Items = new ObservableCollection<object>();
+ this.Groups = new ObservableCollection<string>();
+ }
+
+ public async void CreateBadPerformingData()
+ {
+ var movies = await GetMovies();
+
+ var moviesByYear = movies.GroupBy(x => x.Year);
+
+ foreach (var group in moviesByYear)
+ {
+ var movieGroup = new Category(group.Key.ToString(), group.ToList());
+ MoviesByYear.Add(movieGroup);
+ }
+ }
+
+ public async void CreateDataWithGreatPerformance()
+ {
+ var movies = await GetMovies();
+
+ var moviesByYear = movies.GroupBy(x => x.Year);
+ foreach (var group in moviesByYear)
+ {
+ // The group is added to two collections: Collection containing only the groups and the collection containing movies and the groups
+ this.Groups.Add(group.Key.ToString());
+ this.Items.Add(group.Key.ToString());
+
+ // The movies are only added to the collection containing movies and groups
+ foreach (var movieInfo in group)
+ {
+ this.Items.Add(movieInfo);
+ }
+ }
+ }
+
+ private static async Task<List<MovieInfo>> GetMovies()
+ {
+ var service = new MovieService();
+
+ var movies = await service.GetMovies();
+ return movies;
+ }
+
+ }
+
+
+ public class Category
+ {
+ public string Name { get; set; }
+ public ObservableCollection<MovieInfo> Movies { get; set; }
+
+ public Category(string name, IEnumerable<MovieInfo> movies)
+ {
+ Name = name;
+ this.Movies = new ObservableCollection<MovieInfo>();
+
+ foreach (var movieInfo in movies)
+ {
+ Movies.Add(movieInfo);
+ }
+ }
+ }
+}
18 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/MyTemplateSelector.cs
View
@@ -0,0 +1,18 @@
+using WinRT_GridView_XAML_Performance_Problems.Data;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace WinRT_GridView_XAML_Performance_Problems
+{
+ public class MyTemplateSelector : DataTemplateSelector
+ {
+ protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
+ {
+ var movie = item as MovieInfo;
+ if (movie != null)
+ return (DataTemplate) App.Current.Resources["MovieTemplate"];
+
+ return (DataTemplate)App.Current.Resources["MovieCategoryTemplate"];
+ }
+ }
+}
42 WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Package.appxmanifest
View
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
+
+ <Identity Name="de58e07f-7c42-44d0-b671-a9eeb06aecb6"
+ Publisher="CN=Mikael"
+ Version="1.0.0.0" />
+
+ <Properties>
+ <DisplayName>WinRT-GridView-XAML-Performance-Problems</DisplayName>
+ <PublisherDisplayName>Mikael</PublisherDisplayName>
+ <Logo>Assets\StoreLogo.png</Logo>
+ </Properties>
+
+ <Prerequisites>
+ <OSMinVersion>6.2.1</OSMinVersion>
+ <OSMaxVersionTested>6.2.1</OSMaxVersionTested>
+ </Prerequisites>
+
+ <Resources>
+ <Resource Language="x-generate"/>
+ </Resources>
+
+ <Applications>
+ <Application Id="App"
+ Executable="$targetnametoken$.exe"
+ EntryPoint="WinRT_GridView_XAML_Performance_Problems.App">
+ <VisualElements
+ DisplayName="WinRT-GridView-XAML-Performance-Problems"
+ Logo="Assets\Logo.png"
+ SmallLogo="Assets\SmallLogo.png"
+ Description="WinRT-GridView-XAML-Performance-Problems"
+ ForegroundText="light"
+ BackgroundColor="#464646">
+ <DefaultTile ShowName="allLogos" />
+ <SplashScreen Image="Assets\SplashScreen.png" />
+ </VisualElements>
+ </Application>
+ </Applications>
+ <Capabilities>
+ <Capability Name="internetClient" />
+ </Capabilities>
+</Package>
29 ...T-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems/Properties/AssemblyInfo.cs
View
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("WinRT-GridView-XAML-Performance-Problems")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("WinRT-GridView-XAML-Performance-Problems")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
178 ...rmance-Problems/WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems.csproj
View
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{DD6D0CB1-CB71-4AAA-93C2-16087384A618}</ProjectGuid>
+ <OutputType>AppContainerExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>WinRT_GridView_XAML_Performance_Problems</RootNamespace>
+ <AssemblyName>WinRT-GridView-XAML-Performance-Problems</AssemblyName>
+ <DefaultLanguage>en-US</DefaultLanguage>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <PackageCertificateKeyFile>WinRT-GridView-XAML-Performance-Problems_TemporaryKey.pfx</PackageCertificateKeyFile>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE;NETFX_CORE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\ARM\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>full</DebugType>
+ <PlatformTarget>ARM</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
+ <OutputPath>bin\ARM\Release\</OutputPath>
+ <DefineConstants>TRACE;NETFX_CORE</DefineConstants>
+ <Optimize>true</Optimize>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>ARM</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x64\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <OutputPath>bin\x64\Release\</OutputPath>
+ <DefineConstants>TRACE;NETFX_CORE</DefineConstants>
+ <Optimize>true</Optimize>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+ <OutputPath>bin\x86\Release\</OutputPath>
+ <DefineConstants>TRACE;NETFX_CORE</DefineConstants>
+ <Optimize>true</Optimize>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <ItemGroup>
+ <!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="App.xaml.cs">
+ <DependentUpon>App.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="Data\VideoService.cs" />
+ <Compile Include="BadPerformancePage.xaml.cs">
+ <DependentUpon>BadPerformancePage.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="GoodPerformancePage.xaml.cs">
+ <DependentUpon>GoodPerformancePage.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="MovieDetailsPage.xaml.cs">
+ <DependentUpon>MovieDetailsPage.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="MoviesVm.cs" />
+ <Compile Include="MyTemplateSelector.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Common\BindableBase.cs" />
+ <Compile Include="Common\BooleanToVisibilityConverter.cs" />
+ <Compile Include="Common\BooleanNegationConverter.cs" />
+ <Compile Include="Common\LayoutAwarePage.cs" />
+ <Compile Include="Common\RichTextColumns.cs" />
+ <Compile Include="Common\SuspensionManager.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <AppxManifest Include="Package.appxmanifest">
+ <SubType>Designer</SubType>
+ </AppxManifest>
+ <None Include="Common\ReadMe.txt" />
+ <None Include="WinRT-GridView-XAML-Performance-Problems_TemporaryKey.pfx" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Assets\Logo.png" />
+ <Content Include="Assets\SmallLogo.png" />
+ <Content Include="Assets\SplashScreen.png" />
+ <Content Include="Assets\StoreLogo.png" />
+ <Content Include="Assets\LightGray.png" />
+ <Content Include="Assets\MediumGray.png" />
+ <Content Include="Assets\DarkGray.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <ApplicationDefinition Include="App.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </ApplicationDefinition>
+ <Page Include="Common\StandardStyles.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="BadPerformancePage.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="GoodPerformancePage.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="MovieDetailsPage.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ </ItemGroup>
+ <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '11.0' ">
+ <VisualStudioVersion>11.0</VisualStudioVersion>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
BIN  ...blems/WinRT-GridView-XAML-Performance-Problems/WinRT-GridView-XAML-Performance-Problems_TemporaryKey.pfx
View
Binary file not shown
Please sign in to comment.
Something went wrong with that request. Please try again.