Merged PR 1175800: Implement Pivot/NavigationView duality

With this change, the sample gallery now dynamically chooses whether to load a Pivot control or a NavigationView for hosting and navigating through the samples.  By default it uses a NavigationView where that is available, but can easily be forced to use a Pivot for sanity checking.

The first part of this is creating a C# interface to define the interaction between the hosting UI and the rest of the codebase, and consolidating the navigation model around this.  Previously there were a few different places/methods for navigating to samples/other UI.   Now there is one.

To implement the abstraction, a new UserControl (SampleGalleryUIIndirector) is created that implements the above interface.  MainPage now instantiates one of these.  I'm not a huge fan of requiring this useless control, but having it does provide the nice benefit of having an entity that can be referenced in markup rather than requiring all logic/configuration to be done via code behind.

Two other UserControls are also created - one which implements the Pivot version of the UI, and one which implements the NavigationView version.  They also each implement the hosting interface.  At runtime, the Indirector control determines which one to instantiate, and then forwards all hosting calls onto whichever one it determined.

The Pivot version is implemented mostly the same as the previous version (modulo some bug fixes).

The NavigationView version requires the use of ConditionalMarkup so that it can be defined in markup.  Otherwise, the UI would have to be built and configured completely via code, as the markup compiler runs against your minimum supported version.  This fact will become relevant later on this description :)  This version of the UI is fully functional, but it needs some styling/animations love, and I have some open questions out to the controls team on how to get rid of some of the wonkiness going on there.

There are also a few other miscellaneous cleanup/bug fix things going on here.

This change also bumps the minimum supported version up to RS2, as that is required for conditional XAML support.  Conditional XAML is required for the NavigationView as described above.
This commit is contained in:
Scott Moore 2018-01-02 22:54:31 +00:00 коммит произвёл Danielle Neuberger
Родитель 87ea37b53c 0572844060
Коммит 70cef0c587
17 изменённых файлов: 546 добавлений и 129 удалений

Двоичные данные
SampleGallery/Assets/CategoryIcons/table_depth_icon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 319 KiB

Двоичные данные
SampleGallery/Assets/CategoryIcons/table_light_icon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 262 KiB

Двоичные данные
SampleGallery/Assets/CategoryIcons/table_material_icon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 376 KiB

Двоичные данные
SampleGallery/Assets/CategoryIcons/table_motion_icon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 242 KiB

Двоичные данные
SampleGallery/Assets/CategoryIcons/table_scale_icon.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 335 KiB

Просмотреть файл

@ -27,27 +27,12 @@
<TextBlock Style="{ThemeResource CaptionTextBlockStyle}" Padding="59,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left">Windows UI Sample Gallery</TextBlock>
</Grid>
<Grid Grid.Row="1" >
<Pivot
x:Name="MainPivot"
<local:SampleGalleryUIIndirector
Grid.Row="1"
ItemsSource="{x:Bind Path=MainNavigation.MainMenuList}"
PivotItemLoading="MainPivot_PivotItemLoading"
IsHeaderItemsCarouselEnabled="False">
<Pivot.HeaderTemplate>
<DataTemplate x:DataType="local:NavigationItem">
<TextBlock Text="{x:Bind Path=DisplayName}" />
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate x:DataType="local:NavigationItem">
<Frame
Loaded="Frame_Loaded"
x:Name="PivotItemFrame"
Navigated="MainFrame_Navigated">
</Frame>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
x:Name="GalleryUI"
UIType="Auto"
SampleCategories="{x:Bind Path=MainNavigation.MainMenuList}"/>
<AutoSuggestBox x:Name="SearchBox" QueryIcon="Find" PlaceholderText="Search Samples (Alt+Q)"
Width="300" HorizontalAlignment="Right" Margin="0,7,10,0"
TextChanged="AutoSuggestBox_TextChanged"

Просмотреть файл

@ -35,7 +35,6 @@ namespace CompositionSampleGallery
{
public sealed partial class MainPage : Page
{
private static MainPage _instance;
private ManagedSurface _splashSurface;
#if SDKVERSION_15063
private static CompositionCapabilities _capabilities;
@ -44,15 +43,12 @@ namespace CompositionSampleGallery
private static bool _areEffectsFast;
private static RuntimeSupportedSDKs _runtimeCapabilities;
private MainNavigationViewModel _mainNavigation;
private Frame _currentFrame;
private SampleDefinition _dummySampleDefinition;
public MainPage(Rect imageBounds)
{
_instance = this;
_runtimeCapabilities = new RuntimeSupportedSDKs();
_currentFrame = null;
// Get hardware capabilities and register changed event listener only when targeting the
// appropriate SDK version and the runtime supports this version
@ -71,7 +67,7 @@ namespace CompositionSampleGallery
_areEffectsFast = true;
}
this.InitializeComponent();
_mainNavigation = new MainNavigationViewModel();
_mainNavigation = new MainNavigationViewModel(GalleryUI);
// Initialize the image loader
ImageLoader.Initialize(ElementCompositionPreview.GetElementVisual(this).Compositor);
@ -92,9 +88,6 @@ namespace CompositionSampleGallery
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
titleBar.ButtonForegroundColor = Colors.Black;
// Apply a customized control template to the pivot
MainPivot.Template = (ControlTemplate)Application.Current.Resources["PivotControlTemplate"];
// Apply acrylic to the main navigation
TitleBarRow.Height = new GridLength(31);
TitleBarGrid.Background = (Brush)Application.Current.Resources["SystemControlChromeMediumLowAcrylicWindowMediumBrush"];
@ -104,11 +97,6 @@ namespace CompositionSampleGallery
public MainNavigationViewModel MainNavigation => _mainNavigation;
public static MainPage Instance
{
get { return _instance; }
}
public static bool AreEffectsSupported
{
get { return _areEffectsSupported; }
@ -130,11 +118,7 @@ namespace CompositionSampleGallery
_areEffectsSupported = _capabilities.AreEffectsSupported();
_areEffectsFast = _capabilities.AreEffectsFast();
if (_currentFrame.Content is SampleHost host)
{
SamplePage page = (SamplePage)host.Content;
page.OnCapabiliesChanged(_areEffectsSupported, _areEffectsFast);
}
GalleryUI.NotifyCompositionCapabilitiesChanged(_areEffectsSupported, _areEffectsFast);
SampleDefinitions.RefreshSampleList();
@ -235,8 +219,8 @@ namespace CompositionSampleGallery
scaleUpSplashAnimation.Duration = duration;
// Configure the grid visual to scale from the center
Visual gridVisual = ElementCompositionPreview.GetElementVisual(MainPivot);
gridVisual.Size = new Vector2((float)MainPivot.ActualWidth, (float)MainPivot.ActualHeight);
Visual gridVisual = ElementCompositionPreview.GetElementVisual(GalleryUI);
gridVisual.Size = new Vector2((float)GalleryUI.ActualWidth, (float)GalleryUI.ActualHeight);
gridVisual.CenterPoint = new Vector3(gridVisual.Size.X, gridVisual.Size.Y, 0) * .5f;
@ -273,40 +257,11 @@ namespace CompositionSampleGallery
HideCustomSplashScreen();
}
private void MainFrame_Navigated(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
// Cache a reference to the current frame
_currentFrame = (Frame)sender;
// Show or hide the global back button
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
_currentFrame.CanGoBack ?
AppViewBackButtonVisibility.Visible :
AppViewBackButtonVisibility.Collapsed;
}
public static void FeaturedSampleList_ItemClick(object sender, ItemClickEventArgs e)
{
MainNavigationViewModel.NavigateToSample(sender, e);
}
// Load the category pages into the frame of each PivotItem
private void Frame_Loaded(object sender, RoutedEventArgs e)
{
NavigationItem navItem = (NavigationItem)(((Frame)sender).DataContext);
((Frame)sender).Navigate(navItem.PageType, navItem);
}
// When navigating to a pivotitem, reload the main page and hide the back
// button
private void MainPivot_PivotItemLoading(Pivot sender, PivotItemEventArgs args)
{
NavigationItem navItem = (NavigationItem)((((PivotItemEventArgs)args).Item).DataContext);
Frame pivotItemFrame = (Frame)(((PivotItem)args.Item).ContentTemplateRoot);
pivotItemFrame.Navigate(navItem.PageType, navItem);
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
}
private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
@ -333,7 +288,7 @@ namespace CompositionSampleGallery
{
if (!string.IsNullOrEmpty(args.QueryText) && args.ChosenSuggestion == null)
{
_currentFrame.Navigate(typeof(SearchResultsPage), args.QueryText);
MainNavigationViewModel.ShowSearchResults(args.QueryText);
}
}
@ -345,7 +300,7 @@ namespace CompositionSampleGallery
}
else
{
_currentFrame.Navigate(((SampleDefinition)(args.SelectedItem)).Type, this);
MainNavigationViewModel.NavigateToSample((SampleDefinition)args.SelectedItem);
}
}

Просмотреть файл

@ -16,7 +16,7 @@
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<PackageCertificateKeyFile>CompositionSampleGallery_TemporaryKey.pfx</PackageCertificateKeyFile>
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.14393.0</TargetPlatformMinVersion>
<TargetPlatformMinVersion>10.0.15063.0</TargetPlatformMinVersion>
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
<AppxBundle>Always</AppxBundle>
<AppxBundlePlatforms>x86|x64|arm</AppxBundlePlatforms>
@ -103,6 +103,13 @@
<Compile Include="Pages\SearchResultsPage.xaml.cs">
<DependentUpon>SearchResultsPage.xaml</DependentUpon>
</Compile>
<Compile Include="SampleGalleryNavViewHost.xaml.cs">
<DependentUpon>SampleGalleryNavViewHost.xaml</DependentUpon>
</Compile>
<Compile Include="SampleGalleryPivotHost.xaml.cs">
<DependentUpon>SampleGalleryPivotHost.xaml</DependentUpon>
</Compile>
<Compile Include="SampleGalleryUIIndirector.cs" />
<Compile Include="Samples\SDK 15063\PullToRefresh\PullToRefresh.xaml.cs" Condition="$(TargetPlatformBuild) &gt;14393" />
<Compile Include="Samples\SDK 15063\ShowHideImplicitWebview\ShowHideImplicitWebview.xaml.cs" Condition="$(TargetPlatformBuild) &gt;14393" />
<Compile Include="Samples\SDK 15063\LightInterop\AmbLight.cs" Condition="$(TargetPlatformBuild) &gt;14393" />
@ -283,6 +290,11 @@
<Content Include="Assets\Appointment.png" />
<Content Include="Assets\Background.png" />
<Content Include="Assets\BannerImages\ShyHeader.png" />
<Content Include="Assets\CategoryIcons\table_depth_icon.png" />
<Content Include="Assets\CategoryIcons\table_light_icon.png" />
<Content Include="Assets\CategoryIcons\table_material_icon.png" />
<Content Include="Assets\CategoryIcons\table_motion_icon.png" />
<Content Include="Assets\CategoryIcons\table_scale_icon.png" />
<Content Include="Assets\Damaged_NormalMap.jpg" />
<Content Include="Assets\FB-f-Logo__blue_57.png" />
<Content Include="Assets\Landmarks\SpaceNeedle.png" />
@ -525,6 +537,14 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="SampleGalleryNavViewHost.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="SampleGalleryPivotHost.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Samples\SDK 15063\PullToRefresh\PullToRefresh.xaml" Condition="$(TargetPlatformBuild) &gt;14393">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>

Просмотреть файл

@ -0,0 +1,25 @@
<UserControl
x:Class="CompositionSampleGallery.SampleGalleryNavViewHost"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CompositionSampleGallery"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:contract5Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
Loaded="OnLoaded">
<Grid>
<contract5Present:NavigationView
x:Name="NavView"
IsSettingsVisible="False"
SelectionChanged="NavViewSelectionChanged">
<Frame x:Name="ContentFrame" Margin="24"/>
</contract5Present:NavigationView>
</Grid>
</UserControl>

Просмотреть файл

@ -0,0 +1,118 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
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 User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
namespace CompositionSampleGallery
{
public sealed partial class SampleGalleryNavViewHost : UserControl, ISampleGalleryUIHost
{
object _itemsSource;
public SampleGalleryNavViewHost()
{
this.InitializeComponent();
}
public object SampleCategories
{
get
{
return _itemsSource;
}
set
{
NavView.MenuItems.Clear();
_itemsSource = value;
// Wrap each NavigationItem with a corresponding NavigationViewItem so that it can
// have its text and icon displayed appropriately.
if (_itemsSource != null)
{
List<NavigationViewItem> newItems = new List<NavigationViewItem>();
foreach (NavigationItem item in (ICollection)value)
{
NavigationViewItem navItem = new NavigationViewItem();
navItem.Content = item.DisplayName;
BitmapIcon icon = new BitmapIcon();
if (!String.IsNullOrEmpty(item.ThumbnailUri))
{
icon.UriSource = new Uri(item.ThumbnailUri);
navItem.Icon = icon;
}
navItem.DataContext = item;
NavView.MenuItems.Add(navItem);
}
}
}
}
public bool CanGoBack
{
get
{
return ContentFrame.CanGoBack;
}
}
public void GoBack()
{
ContentFrame.GoBack();
FireBackStackChangedEvent();
}
public event EventHandler BackStackStateChanged;
public void Navigate(Type type, object parameter)
{
ContentFrame.Navigate(type, parameter);
FireBackStackChangedEvent();
}
public void NotifyCompositionCapabilitiesChanged(bool areEffectsSupported, bool areEffectsFast)
{
if (ContentFrame.Content is SampleHost host)
{
SamplePage page = (SamplePage)host.Content;
page.OnCapabiliesChanged(areEffectsSupported, areEffectsFast);
}
}
private void FireBackStackChangedEvent()
{
BackStackStateChanged?.Invoke(this, EventArgs.Empty);
}
private void NavViewSelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
NavigationItem navItem = (NavigationItem)((NavigationViewItem)args.SelectedItem).DataContext;
ContentFrame.Navigate(navItem.PageType, navItem);
// Reset the backstack when a new category is selected to avoid having to coordinate the cateogory
// selection as we navigate back through the backstack
ContentFrame.BackStack.Clear();
FireBackStackChangedEvent();
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
NavView.SelectedItem = NavView.MenuItems[0];
}
}
}

Просмотреть файл

@ -0,0 +1,33 @@
<UserControl
x:Class="CompositionSampleGallery.SampleGalleryPivotHost"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CompositionSampleGallery"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Pivot
x:Name="MainPivot"
ItemsSource="{x:Bind Path=SampleCategories}"
PivotItemLoading="MainPivot_PivotItemLoading"
IsHeaderItemsCarouselEnabled="False">
<Pivot.HeaderTemplate>
<DataTemplate x:DataType="local:NavigationItem">
<TextBlock Text="{x:Bind Path=DisplayName}" />
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate x:DataType="local:NavigationItem">
<Frame
Loaded="Frame_Loaded"
x:Name="ItemFrame"
Navigated="ItemFrame_Navigated">
</Frame>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
</UserControl>

Просмотреть файл

@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
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 User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
namespace CompositionSampleGallery
{
public sealed partial class SampleGalleryPivotHost : ISampleGalleryUIHost
{
private Frame _currentItemFrame;
public SampleGalleryPivotHost()
{
this.InitializeComponent();
#if SDKVERSION_16299
// Apply a customized control template to the pivot
MainPivot.Template = (ControlTemplate)Application.Current.Resources["PivotControlTemplate"];
#endif
}
public object SampleCategories
{
get
{
return MainPivot.ItemsSource;
}
set
{
MainPivot.ItemsSource = value;
}
}
public event EventHandler BackStackStateChanged;
public bool CanGoBack
{
get
{
return _currentItemFrame != null ? _currentItemFrame.CanGoBack : false;
}
}
public void GoBack()
{
_currentItemFrame.GoBack();
FireBackStackChangedEvent();
}
public void Navigate(Type type, object parameter)
{
_currentItemFrame?.Navigate(type, parameter);
FireBackStackChangedEvent();
}
public void NotifyCompositionCapabilitiesChanged(bool areEffectsSupported, bool areEffectsFast)
{
if (_currentItemFrame != null)
{
if (_currentItemFrame.Content is SampleHost host)
{
SamplePage page = (SamplePage)host.Content;
page.OnCapabiliesChanged(areEffectsSupported, areEffectsFast);
}
}
}
private void ItemFrame_Navigated(object sender, Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
// Cache a reference to the currently displayed item frame. Note that
// this will be a different frame instance per pivot item.
_currentItemFrame = (Frame)sender;
}
// When navigating to a pivotitem, reload the main page and hide the back
// button
private void MainPivot_PivotItemLoading(Pivot sender, PivotItemEventArgs args)
{
NavigationItem navItem = (NavigationItem)((((PivotItemEventArgs)args).Item).DataContext);
Frame pivotItemFrame = (Frame)(((PivotItem)args.Item).ContentTemplateRoot);
pivotItemFrame.Navigate(navItem.PageType, navItem);
pivotItemFrame.BackStack.Clear();
FireBackStackChangedEvent();
}
// Load the category pages into the frame of each PivotItem
private void Frame_Loaded(object sender, RoutedEventArgs e)
{
Frame frame = (Frame)sender;
NavigationItem navItem = (NavigationItem)(frame.DataContext);
frame.Navigate(navItem.PageType, navItem);
frame.BackStack.Clear();
FireBackStackChangedEvent();
}
private void FireBackStackChangedEvent()
{
BackStackStateChanged?.Invoke(this, EventArgs.Empty);
}
}
}

Просмотреть файл

@ -0,0 +1,153 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation.Metadata;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace CompositionSampleGallery
{
// Defines the protocol needed for an abstract sample hosting UI:
// - Setting the list of sample categories
// - Navigating to arbitrary UI
// - Interacting with the navigation back stack
// - Refreshing the current sample when the current composition capabilities have changed
public interface ISampleGalleryUIHost
{
object SampleCategories { get; set; }
bool CanGoBack { get; }
void GoBack();
event EventHandler BackStackStateChanged;
void Navigate(Type type, object parameter);
void NotifyCompositionCapabilitiesChanged(bool areEffectsSupported, bool areEffectsFast);
}
public enum UIType
{
Auto, // Automatically choose a Pivot or NavigationView depending on the current platform
NavView, // Force a NavigationView view to be loaded
Pivot // Force a Pivot view to be loaded
}
// This control allows a level of indirection so that we can host our samples within either a Pivot control on downlevel
// platforms, or a NavigationView control if it is available.
//
// The differences between these two controls are abstracted via the ISampleGalleryUIHost interface,
// which is how external code should interface with this control.
public class SampleGalleryUIIndirector : UserControl, ISampleGalleryUIHost
{
ISampleGalleryUIHost _actualContent;
private object _sampleCategories;
public SampleGalleryUIIndirector()
{
}
private void LoadUI(UIType type)
{
// Auto-detect the type to load if requested
if (type == UIType.Auto)
{
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 5))
{
type = UIType.NavView;
}
else
{
type = UIType.Pivot;
}
}
// Save off any properties that are stashed on the UI itself and need to be
// forwarded on to the new UI, load it, and then reapply the saved properties
object oldItemsSource = SampleCategories;
UIElement actualContent;
if (type == UIType.Pivot)
{
actualContent = new SampleGalleryPivotHost();
}
else
{
actualContent = new SampleGalleryNavViewHost();
}
Content = actualContent;
_actualContent = (ISampleGalleryUIHost)actualContent;
SampleCategories = oldItemsSource;
}
// Convenience helper for forcing into Pivot mode for testing
public UIType UIType
{
set
{
LoadUI(value);
}
}
public object SampleCategories
{
get
{
return _sampleCategories;
}
set
{
_sampleCategories = value;
if (_actualContent != null)
{
_actualContent.SampleCategories = value;
}
}
}
public bool CanGoBack
{
get
{
return _actualContent.CanGoBack;
}
}
public void GoBack()
{
_actualContent.GoBack();
}
public event EventHandler BackStackStateChanged
{
add
{
_actualContent.BackStackStateChanged += value;
}
remove
{
_actualContent.BackStackStateChanged -= value;
}
}
public void Navigate(Type type, object parameter)
{
_actualContent.Navigate(type, parameter);
}
public void NotifyCompositionCapabilitiesChanged(bool areEffectsSupported, bool areEffectsFast)
{
_actualContent.NotifyCompositionCapabilitiesChanged(areEffectsSupported, areEffectsFast);
}
}
}

Просмотреть файл

@ -92,13 +92,11 @@ namespace CompositionSampleGallery
Model.Selected = (FeaturedFlipViewSample)((FlipView)sender).SelectedItem;
}
// Get the frame that this flipviewindicator is a child of, and then navigate to the
// sample that the user selected
// Navigate to the sample that the user selected
private void Button_Click(object sender, RoutedEventArgs e)
{
FeaturedFlipViewSample SelectedSample = BannerFlipView.SelectedItem as FeaturedFlipViewSample;
Frame mainPivotFrame = MainNavigationViewModel.GetPivotFrame(this);
mainPivotFrame.Navigate(typeof(SampleHost), SelectedSample.SampleDefinition);
MainNavigationViewModel.NavigateToSample(SelectedSample.SampleDefinition);
}
private void IndicatorClick(object sender, RoutedEventArgs e)

Просмотреть файл

@ -12,9 +12,11 @@
//
//*********************************************************
using CompositionSampleGallery.Pages;
using System;
using System.Collections.Generic;
using System.Linq;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
@ -22,6 +24,8 @@ namespace CompositionSampleGallery
{
public class MainNavigationViewModel
{
private static MainNavigationViewModel s_instance;
public ISampleGalleryUIHost _hostingUI;
private List<NavigationItem> _mainMenuList;
// Category description text
@ -39,68 +43,82 @@ namespace CompositionSampleGallery
@"In addition to the samples that display the Fluent building blocks in UI, some simple API reference samples are provided to ramp up and learn about basic API capabilities.";
void AddNavigationItem(ref List<NavigationItem> menu, String displayName, SampleCategory cat, Type pageType, string categoryDescription="")
void AddNavigationItem(
List<NavigationItem> menu,
String displayName,
SampleCategory cat,
Type pageType,
string categoryDescription="",
bool addEvenIfNoMatchingSamples = false,
string thumbnail="")
{
var samples = from sample in SampleDefinitions.Definitions
where (sample.SampleCategory == cat)
select sample;
if (samples.Count<SampleDefinition>() > 0)
if ((samples.Count<SampleDefinition>() > 0) || addEvenIfNoMatchingSamples)
{
menu.Add(new NavigationItem(displayName, cat, pageType, categoryDescription: categoryDescription));
menu.Add(new NavigationItem(displayName, cat, pageType, categoryDescription: categoryDescription, thumbnail:thumbnail));
}
}
public MainNavigationViewModel()
public MainNavigationViewModel(ISampleGalleryUIHost hostingUI)
{
_hostingUI = hostingUI;
_hostingUI.BackStackStateChanged += (object sender, EventArgs args) =>
{
// Show or hide the global back button
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
_hostingUI.CanGoBack ?
AppViewBackButtonVisibility.Visible :
AppViewBackButtonVisibility.Collapsed;
};
SystemNavigationManager.GetForCurrentView().BackRequested += (object backSender, BackRequestedEventArgs backArgs) =>
{
_hostingUI.GoBack();
};
// Build a collection used to populate the navigation menu. This is where you can define the display names of
// each menu item and which page they map to.
_mainMenuList = new List<NavigationItem>();
_mainMenuList.Add(new NavigationItem("Home", SampleCategory.Light /* unused */, typeof(HomePage)));
AddNavigationItem(ref _mainMenuList, "Light", SampleCategory.Light, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_Light);
AddNavigationItem(ref _mainMenuList, "Depth", SampleCategory.Depth, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_Depth);
AddNavigationItem(ref _mainMenuList, "Motion", SampleCategory.Motion, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_Motion);
AddNavigationItem(ref _mainMenuList, "Material", SampleCategory.Material, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_Material);
AddNavigationItem(ref _mainMenuList, "Scale", SampleCategory.Scale, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_Scale);
AddNavigationItem(ref _mainMenuList, "API Reference", SampleCategory.APIReference, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_APIReference);
AddNavigationItem(_mainMenuList, "Home", SampleCategory.None, typeof(HomePage), addEvenIfNoMatchingSamples: true);
AddNavigationItem(_mainMenuList, "Light", SampleCategory.Light, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_Light, thumbnail: "ms-appx:///Assets/CategoryIcons/table_light_icon.png");
AddNavigationItem(_mainMenuList, "Depth", SampleCategory.Depth, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_Depth, thumbnail: "ms-appx:///Assets/CategoryIcons/table_depth_icon.png");
AddNavigationItem(_mainMenuList, "Motion", SampleCategory.Motion, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_Motion, thumbnail: "ms-appx:///Assets/CategoryIcons/table_motion_icon.png");
AddNavigationItem(_mainMenuList, "Material", SampleCategory.Material, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_Material, thumbnail: "ms-appx:///Assets/CategoryIcons/table_material_icon.png");
AddNavigationItem(_mainMenuList, "Scale", SampleCategory.Scale, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_Scale, thumbnail: "ms-appx:///Assets/CategoryIcons/table_scale_icon.png");
AddNavigationItem(_mainMenuList, "API Reference", SampleCategory.APIReference, typeof(BaseCategoryPage), categoryDescription: CategoryDescription_APIReference);
s_instance = this;
}
public List<NavigationItem> MainMenuList => _mainMenuList;
// When a sample item is clicked, walk up and find the parent frame and
// have that frame navigate to the sample
public static void NavigateToSample(object sender, ItemClickEventArgs e)
{
Frame pivotItemFrame = GetPivotFrame((FrameworkElement)sender);
if(pivotItemFrame != null)
{
SampleDefinition sample = (SampleDefinition)e.ClickedItem;
pivotItemFrame.Navigate(typeof(SampleHost), sample);
}
NavigateToSample((SampleDefinition)e.ClickedItem);
}
// Given a UIElement, walk up the logical tree until the main pivot frame
// is found
public static Frame GetPivotFrame(FrameworkElement element)
public static void NavigateToSample(SampleDefinition sample)
{
FrameworkElement parent = (FrameworkElement)element.Parent;
while (parent != null)
{
if (parent.GetType() == typeof(Frame) && parent.Name == "PivotItemFrame")
{
break;
}
parent = (FrameworkElement)parent.Parent;
}
return (Frame)parent;
s_instance._hostingUI.Navigate(typeof(SampleHost), sample);
}
public static void ShowSearchResults(string queryText)
{
s_instance._hostingUI.Navigate(typeof(SearchResultsPage), queryText);
}
}
public class NavigationItem
{
private string _displayName, _featuredSamplesTitle;
private string _thumbnail;
private string _displayName;
private string _featuredSamplesTitle;
private Type _pageType;
private SampleCategory _cat;
private string _categoryDescription;
@ -110,13 +128,20 @@ namespace CompositionSampleGallery
public SampleCategory Category { get { return _cat; } set { _cat = value; } }
public string FeaturedSamplesTitle { get { return _featuredSamplesTitle; } set { _featuredSamplesTitle = value; } }
public string CategoryDescription { get { return _categoryDescription; } }
public NavigationItem(string displayName, SampleCategory cat, Type pageType, string featuredSamplesTitle = "", string categoryDescription="")
public string ThumbnailUri { get { return _thumbnail; } }
public NavigationItem(
string displayName,
SampleCategory cat,
Type pageType,
string categoryDescription,
string thumbnail)
{
_displayName = displayName;
_pageType = pageType;
_cat = cat;
_featuredSamplesTitle = featuredSamplesTitle;
_featuredSamplesTitle = "";
_categoryDescription = categoryDescription;
_thumbnail = thumbnail;
}
}
}

Просмотреть файл

@ -27,6 +27,7 @@ namespace CompositionSampleGallery
public enum SampleCategory
{
None,
Light,
Depth,
Motion,

Просмотреть файл

@ -28,28 +28,14 @@ namespace CompositionSampleGallery
{
base.OnNavigatedTo(e);
Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested += SamplePage_BackRequested;
if (e.Parameter is SampleHost)
if (e.Parameter is SampleHost host)
{
SampleHost host = (SampleHost)e.Parameter;
host.SampleDescription.Text = SampleDescription;
host.SampleName.Text = SampleName;
host.SampleCode.NavigateUri = new Uri(SampleCodeUri);
}
}
private void SamplePage_BackRequested(object sender, Windows.UI.Core.BackRequestedEventArgs e)
{
Frame pivotItemFrame = MainNavigationViewModel.GetPivotFrame(this);
if (pivotItemFrame != null)
{
e.Handled = true;
(pivotItemFrame).GoBack();
}
}
public virtual void OnCapabiliesChanged(bool areEffectSupported, bool areEffectsFast)
{