Skip to content

Commit

Permalink
Adds NavigationController to Windows Phone tools
Browse files Browse the repository at this point in the history
NavigationController is no longer static, so multiple navigation controllers can be used with multiple frames within one application.

The existing ExtendedSplashScreen was modified to support the new NavigationController and an ExtendedSplashScreen for Windows Phone was created.
  • Loading branch information
madd0 committed Aug 29, 2013
1 parent 65869d4 commit 02d7dc6
Show file tree
Hide file tree
Showing 12 changed files with 953 additions and 417 deletions.
22 changes: 0 additions & 22 deletions Wygwam.Windows.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhoneTester", "PhoneTester\PhoneTester.csproj", "{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -67,26 +65,6 @@ Global
{8AD870BE-26B6-4290-92D8-6DACDA602512}.Release|x64.Build.0 = Release|x64
{8AD870BE-26B6-4290-92D8-6DACDA602512}.Release|x86.ActiveCfg = Release|x86
{8AD870BE-26B6-4290-92D8-6DACDA602512}.Release|x86.Build.0 = Release|x86
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Debug|ARM.ActiveCfg = Debug|ARM
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Debug|ARM.Build.0 = Debug|ARM
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Debug|ARM.Deploy.0 = Debug|ARM
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Debug|x64.ActiveCfg = Debug|Any CPU
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Debug|x86.ActiveCfg = Debug|x86
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Debug|x86.Build.0 = Debug|x86
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Debug|x86.Deploy.0 = Debug|x86
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Release|Any CPU.Build.0 = Release|Any CPU
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Release|Any CPU.Deploy.0 = Release|Any CPU
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Release|ARM.ActiveCfg = Release|ARM
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Release|ARM.Build.0 = Release|ARM
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Release|ARM.Deploy.0 = Release|ARM
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Release|x64.ActiveCfg = Release|Any CPU
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Release|x86.ActiveCfg = Release|x86
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Release|x86.Build.0 = Release|x86
{C74A4CE3-5BB3-4FAF-9528-E3586D7102B4}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
91 changes: 91 additions & 0 deletions WygwamToolkit.Phone/Controls/ExtendedSplashScreen.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//-----------------------------------------------------------------------
// <copyright file="ExtendedSplashScreen.cs" company="Wygwam">
// Copyright (c) 2013 Wygwam.
// Licensed under the Microsoft Public License (Ms-PL) (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://opensource.org/licenses/Ms-PL.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
//-----------------------------------------------------------------------

namespace Wygwam.Windows.Controls
{
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System;
using System.Windows;
using System.Windows.Media;
using Wygwam.Windows.ViewModels;
using System.Reflection;

public partial class ExtendedSplashScreen : BaseExtendedSplashScreen
{
private NavigationController _navigationController;

private Type _nextPage;

public ExtendedSplashScreen()
{
this.FontFamily = (FontFamily)Application.Current.Resources["PhoneFontFamilyNormal"];
this.FontSize=(double)Application.Current.Resources["PhoneFontSizeNormal"];
this.Foreground=(Brush)Application.Current.Resources["PhoneForegroundBrush"];

this.Orientation = PageOrientation.Portrait;
this.SupportedOrientations = SupportedPageOrientation.Portrait;

this.SetValue(SystemTray.IsVisibleProperty, false);

this.Loaded += this.OnLoaded;
}

/// <summary>
/// Initializes a new instance of the <see cref="ExtendedSplashScreen"/> class.
/// </summary>
/// <param name="navigationController">The navigation controller used to navigate away from the splash screen.</param>
/// <param name="args">The <see cref="IActivatedEventArgs"/> instance provided by the
/// application when it was launched.</param>
/// <param name="nextPage">The type of the page to which the application will navigate when loading is done.</param>
/// <param name="parameter">An optional navigation parameter.</param>
public ExtendedSplashScreen(NavigationController navigationController, Type nextPageViewModel, object parameter = null)
: this()
{
_navigationController = navigationController;

_nextPage = nextPageViewModel;

this.NavigationParameter = parameter;
}

private async void OnLoaded(object sender, RoutedEventArgs e)
{
await this.PerformLoadingActionAsync().ContinueWith(
_ =>
{
if (this.AdvancesAutomatically)
{
this.IsDone = true;
}
},
this.UIScheduler);
}

protected override void MoveToNextPage()
{
_navigationController.GoToType(_nextPage);

var nextPage = _navigationController.CurrentView;

if (nextPage != null)
{
nextPage.NavigationService.RemoveBackEntry();
}
}
}
}
72 changes: 72 additions & 0 deletions WygwamToolkit.Phone/DefaultWindowManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//-----------------------------------------------------------------------
// <copyright file="DefaultWindowManager.cs" company="Wygwam">
// Copyright (c) 2013 Wygwam.
// Licensed under the Microsoft Public License (Ms-PL) (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://opensource.org/licenses/Ms-PL.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
//-----------------------------------------------------------------------

namespace Wygwam.Windows
{
using Microsoft.Phone.Controls;
using System.Windows;
using System.Windows.Controls;

/// <summary>
/// An implementation of <see cref="T:IWindowManager"/> that provides the content
/// of the app window as a <see cref="global::Windows.UI.Xaml.Controls.Frame"/> or sets
/// a new <see cref="global::Windows.UI.Xaml.Controls.Frame"/> if necessary.
/// </summary>
public class DefaultWindowManager : IWindowManager
{
/// <summary>
/// Gets the <see cref="global::Windows.UI.Xaml.Controls.Frame" /> used for navigation if it exists.
/// </summary>
/// <remarks>
/// Use <see cref="M:EnsureNaviationFrameExists" /> if you need to be sure that a frame for
/// navigation exits (e.g. when the application navigates to its first page.)
/// </remarks>
public Frame NavigationFrame
{
get
{
return Application.Current.RootVisual as Frame;
}

private set
{
Application.Current.RootVisual = value;
}
}

/// <summary>
/// Ensures the navigation frame exists.
/// </summary>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
/// <remarks>
/// Implementation of this method should check that a frame is available that can be used for
/// navigation. If it isn't, it should take the necessary steps to create one and set the contents of
/// the current <see cref="global::Windows.UI.Xaml.Window" /> appropriately.
/// </remarks>
public Frame EnsureNavigationFrameExists()
{
if (this.NavigationFrame == null)
{
// Create a Frame to act as the navigation context and set it as window content
this.NavigationFrame = new PhoneApplicationFrame();
}

return this.NavigationFrame;
}
}
}
127 changes: 127 additions & 0 deletions WygwamToolkit.Phone/NavigationController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//-----------------------------------------------------------------------
// <copyright file="NavigationController.cs" company="Wygwam">
// Copyright (c) 2013 Wygwam.
// Licensed under the Microsoft Public License (Ms-PL) (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://opensource.org/licenses/Ms-PL.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
//-----------------------------------------------------------------------

namespace Wygwam.Windows
{
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using Wygwam.Windows.ViewModels;

/// <summary>
/// Provides MVVM-compatible navigation for Windows Store Apps.
/// </summary>
public class NavigationController : BaseNavigationController
{
private readonly Dictionary<Type, Uri> _viewModelMap = new Dictionary<Type, Uri>();

private Frame _currentNavigationFrame;

private object _pendingNavigationParameter;

/// <summary>
/// Associates a view type with a view model type.
/// </summary>
/// <typeparam name="TViewModel">The type of the view model. This must extend <see cref="BaseViewModel" />.</typeparam>
/// <typeparam name="TView">The type of the view. This must be a <see cref="global::Windows.UI.Xaml.Controls.Page" />.</typeparam>
/// <seealso cref="M:GoTo{TViewModel}" />
/// <remarks>
/// A new instance of the view model will be created at runtime by reflection when you
/// navigate. The constructor of the view model will receive any parameters that you pass during navigation.
/// </remarks>
public void Register<TViewModel>(Uri pageUri)
where TViewModel : BaseViewModel
{
this.Register<TViewModel>(pageUri, args => (TViewModel)Activator.CreateInstance(typeof(TViewModel), args));
}

/// <summary>
/// Associates a view type with a view model type.
/// </summary>
/// <typeparam name="TViewModel">The type of the view model. This must extend <see cref="BaseViewModel" />.</typeparam>
/// <typeparam name="TView">The type of the view. This must be a <see cref="global::Windows.UI.Xaml.Controls.Page" />.</typeparam>
/// <param name="instance">An instance of the view model that will be used as a singleton during navigation operations.</param>
/// <seealso cref="M:GoTo{TViewModel}" />
/// <remarks>
/// The same instance of the view model will used for every navigation operation.
/// </remarks>
public void Register<TViewModel>(Uri pageUri, TViewModel instance)
where TViewModel : BaseViewModel
{
this.Register<TViewModel>(pageUri, _ => instance);
}

/// <summary>
/// Associates a view type with a view model type.
/// </summary>
/// <typeparam name="TViewModel">The type of the view model. This must extend <see cref="BaseViewModel" />.</typeparam>
/// <typeparam name="TView">The type of the view. This must be a <see cref="global::Windows.UI.Xaml.Controls.Page" />.</typeparam>
/// <param name="delegate">A delegate that will create an instance of the view model during navigation.</param>
/// <seealso cref="M:GoTo{TViewModel}" />
/// <remarks>
/// The provided delegate must return the desired instance of the view model. It will be provided an array of arguments
/// that can be used to create or initialize the view model.
/// </remarks>
public void Register<TViewModel>(Uri pageUri, Func<object[], TViewModel> @delegate)
where TViewModel : BaseViewModel
{
var type = typeof(TViewModel);

_viewModelMap.Add(type, pageUri);

this.RegisterViewModelGenerator<TViewModel>(type, @delegate);
}

protected override bool NavigateToType(Type viewModelType, object viewModelInstance)
{
var frame = this.WindowManager.EnsureNavigationFrameExists();

if (frame != _currentNavigationFrame)
{
if (_currentNavigationFrame != null)
{
_currentNavigationFrame.Navigated -= this.OnFrameNavigated;
}

_currentNavigationFrame = frame;
_currentNavigationFrame.Navigated += this.OnFrameNavigated;
}

_pendingNavigationParameter = viewModelInstance;

return frame.Navigate(_viewModelMap[viewModelType]);
}

protected override bool IsViewModelRegistered(Type viewModelType)
{
return _viewModelMap.ContainsKey(viewModelType);
}

private void OnFrameNavigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
var navigationTarget = e.Content as FrameworkElement;

if (navigationTarget != null)
{
navigationTarget.DataContext = _pendingNavigationParameter;
}

_pendingNavigationParameter = null;
}
}
}
15 changes: 15 additions & 0 deletions WygwamToolkit.Phone/Wygwam.Windows.Phone.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,26 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\WygwamToolkit.WinRT\BaseNavigationController.cs">
<Link>BaseNavigationController.cs</Link>
</Compile>
<Compile Include="..\WygwamToolkit.WinRT\Controls\BaseExtendedSplashScreen.cs">
<Link>Controls\BaseExtendedSplashScreen.cs</Link>
</Compile>
<Compile Include="..\WygwamToolkit.WinRT\Extensions\VisualState.cs">
<Link>Extensions\VisualState.cs</Link>
</Compile>
<Compile Include="..\WygwamToolkit.WinRT\IWindowManager.cs">
<Link>IWindowManager.cs</Link>
</Compile>
<Compile Include="Controls\ExtendedSplashScreen.cs" />
<Compile Include="DefaultWindowManager.cs" />
<Compile Include="Info\DeviceInfo.cs" />
<Compile Include="Managers\LocationManager.cs" />
<Compile Include="Managers\ManifestManager.cs" />
<Compile Include="Managers\NetworkManager.cs" />
<Compile Include="Managers\StorageManager.cs" />
<Compile Include="NavigationController.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Security\SecurePassword.cs" />
<Compile Include="SmartDispatcher.cs" />
Expand Down
Loading

0 comments on commit 02d7dc6

Please sign in to comment.