IoC and NavigationService implementation

This commit is contained in:
2011-03-25 11:22:57 +02:00
parent 98c8cf3f94
commit f069ee7010
31 changed files with 1139 additions and 73 deletions
+5 -1
View File
@@ -34,6 +34,9 @@ namespace MyFriendsAround.WP7
// Phone-specific initialization
InitializePhoneApplication();
//register ViewModelLocator
Container.Instance.RegisterInstance(typeof(ViewModelLocator), "ViewModelLocator");
}
// Code to execute when the application is launching (eg, from Start)
@@ -58,7 +61,8 @@ namespace MyFriendsAround.WP7
// This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
ViewModelLocator.Cleanup();
ViewModelLocator locator = Container.Instance.Resolve<ViewModelLocator>();
locator.Cleanup();
}
// Code to execute if a navigation fails
@@ -0,0 +1,23 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
namespace MyFriendsAround.WP7.Helpers.Navigation
{
public interface IPageNavigation
{
event NavigatingCancelEventHandler Navigating;
object CurrentContext { get; }
void NavigateTo(Uri pageUri);
void NavigateTo(Uri pageUri, object context);
void GoBack();
}
}
@@ -0,0 +1,82 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Navigation;
namespace MyFriendsAround.WP7.Helpers.Navigation
{
public class PageNavigation : IPageNavigation
{
private PhoneApplicationFrame mainFrame;
private bool EnsureMainFrame()
{
if (mainFrame != null)
{
return true;
}
mainFrame = Application.Current.RootVisual as PhoneApplicationFrame;
if (mainFrame != null)
{
// Could be null if the app runs inside a design tool
mainFrame.Navigating += (s, e) =>
{
if (Navigating != null)
{
Navigating(s, e);
}
};
return true;
}
return false;
}
#region IPageNavigation implementation
public event NavigatingCancelEventHandler Navigating;
private object currentContext;
public object CurrentContext
{
get { return this.currentContext; }
}
public void NavigateTo(Uri pageUri)
{
if (pageUri == null)
throw new ArgumentNullException("uri");
if (EnsureMainFrame())
this.NavigateTo(pageUri, null);
}
public void NavigateTo(Uri pageUri, object context)
{
if (pageUri == null)
throw new ArgumentNullException("uri");
if (EnsureMainFrame())
{
this.currentContext = context;
mainFrame.Navigate(pageUri);
}
}
public void GoBack()
{
if (EnsureMainFrame() && mainFrame.CanGoBack)
{
mainFrame.GoBack();
}
}
#endregion
}
}
@@ -116,7 +116,12 @@
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="MainPage.xaml.cs">
<Compile Include="Helpers\Navigation\IPageNavigation.cs" />
<Compile Include="Helpers\Navigation\PageNavigation.cs" />
<Compile Include="Views\AboutPage.xaml.cs">
<DependentUpon>AboutPage.xaml</DependentUpon>
</Compile>
<Compile Include="Views\MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -126,8 +131,11 @@
<Compile Include="Tests\Tests1.cs" />
<Compile Include="Utils\Identification.cs" />
<Compile Include="Utils\SerializationHelper.cs" />
<Compile Include="ViewModel\Container.cs" />
<Compile Include="ViewModel\AboutViewModel.cs" />
<Compile Include="ViewModel\MainViewModel.cs" />
<Compile Include="ViewModel\PushPinModel.cs" />
<Compile Include="ViewModel\ViewModelBase.cs" />
<Compile Include="ViewModel\ViewModelLocator.cs" />
</ItemGroup>
<ItemGroup>
@@ -135,7 +143,11 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="MainPage.xaml">
<Page Include="Views\AboutPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\MainPage.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
@@ -158,12 +170,11 @@
<Content Include="icons\appbar.questionmark.rest.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="README_FIRST.txt" />
<Content Include="SplashScreenImage.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Resource Include="Toolkit.Content\ApplicationBar.Cancel.png" />
<Resource Include="Toolkit.Content\ApplicationBar.Check.png" />
<Content Include="Toolkit.Content\ApplicationBar.Cancel.png" />
<Content Include="Toolkit.Content\ApplicationBar.Check.png" />
</ItemGroup>
<ItemGroup>
<Folder Include="Model\" />
@@ -176,6 +187,10 @@
<Project>{A128812A-1249-4562-BDF4-5E17951B8434}</Project>
<Name>GpsEmulatorClient</Name>
</ProjectReference>
<ProjectReference Include="..\Libs\MicroIoc\MicroIoc.Core\MicroIoc.Core.csproj">
<Project>{23F63AE9-A436-4B27-9113-4142C09ADD08}</Project>
<Name>MicroIoc.Core</Name>
</ProjectReference>
<ProjectReference Include="..\Libs\Phone7.Fx.Preview\Phone7.Fx.Preview.csproj">
<Project>{B55A0F90-2B5A-4C4B-88F4-013AA1629866}</Project>
<Name>Phone7.Fx.Preview</Name>
@@ -17,7 +17,7 @@
<Capability Name="ID_CAP_IDENTITY_USER" />
</Capabilities>
<Tasks>
<DefaultTask Name ="_default" NavigationPage="MainPage.xaml"/>
<DefaultTask Name ="_default" NavigationPage="Views\MainPage.xaml"/>
</Tasks>
<Tokens>
<PrimaryToken TokenID="MyFriendsAround.WP7Token" TaskName="_default">
@@ -1,3 +0,0 @@
For the Silverlight for Windows Phone Toolkit make sure that you have
marked the icons in the "Toolkit.Content" folder as content. That way they
can be used as the icons for the ApplicationBar control.
@@ -28,5 +28,6 @@ namespace MyFriendsAround.WP7.Utils
{
return JsonConvert.SerializeObject(obj);
}
}
}
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Device.Location;
using System.Net;
using System.ServiceModel.Channels;
using System.Windows;
using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight.Threading;
using Hammock;
using Hammock.Serialization;
using Microsoft.Phone.Controls;
using Microsoft.Silverlight.Testing;
using MyFriendsAround.Common.Entities;
using MyFriendsAround.WP7.Service;
using MyFriendsAround.WP7.Utils;
using Newtonsoft.Json;
namespace MyFriendsAround.WP7.ViewModel
{
public class AboutViewModel : ViewModelBase
{
public string ApplicationTitle
{
get
{
return "MyFriendsAround";
}
}
public string PageName
{
get
{
return "About";
}
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public AboutViewModel()
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
// Code runs "for real"
}
}
public string AppBarTextAbout {
get { return "About"; }
}
public string AppBarTextPublish
{
get { return "Publish"; }
}
}
}
@@ -0,0 +1,40 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using MicroIoc;
namespace MyFriendsAround.WP7.ViewModel
{
public sealed class Container
{
Container()
{
}
public static IMicroIocContainer Instance
{
get
{
return Nested.instance;
}
}
class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as before field init
static Nested()
{
}
internal static readonly IMicroIocContainer instance =
new MicroIocContainer();
}
}
}
@@ -51,14 +51,6 @@ namespace MyFriendsAround.WP7.ViewModel
}
}
public string Welcome
{
get
{
return "Welcome to MVVM Light";
}
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
@@ -68,6 +60,7 @@ namespace MyFriendsAround.WP7.ViewModel
PublishLocationCommand = new RelayCommand(() => PublishLocationAction());
DisplayAboutCommand = new RelayCommand(() => DisplayAbout());
InputBoxCommand = new RelayCommand(() => InputBox());
NavigateToAboutCommand = new RelayCommand(() => NavigateToAbout());
if (IsInDesignMode)
{
@@ -82,6 +75,12 @@ namespace MyFriendsAround.WP7.ViewModel
}
private void NavigateToAbout()
{
//
this.PageNav.NavigateTo(new Uri("/Views/AboutPage.xaml", UriKind.Relative));
}
private void InputBox()
{
MessageBox.Show("Input box");
@@ -102,7 +101,7 @@ namespace MyFriendsAround.WP7.ViewModel
//f.LocationStr
result.Add(new PushPinModel()
{
PinSource = "ApplicationIcon.png",
PinSource = "/ApplicationIcon.png",
Location = new GeoCoordinate(f.Latitude, f.Longitude)
});
});
@@ -161,10 +160,17 @@ namespace MyFriendsAround.WP7.ViewModel
}
}
public RelayCommand PublishLocationCommand { get; set; }
public RelayCommand DisplayAboutCommand { get; set; }
public RelayCommand InputBoxCommand { get; set; }
public ICommand PublishLocationCommand { get; set; }
public ICommand DisplayAboutCommand { get; set; }
public ICommand InputBoxCommand { get; set; }
public ICommand NavigateToAboutCommand
{
get;
private set;
}
public string MyName { get; set; }
public string AppBarTextAbout {
@@ -0,0 +1,43 @@
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using MyFriendsAround.WP7.Helpers.Navigation;
namespace MyFriendsAround.WP7.ViewModel
{
public class ViewModelBase : GalaSoft.MvvmLight.ViewModelBase
{
private object context;
public object Context
{
get { return context; }
set
{
if (context == value)
return;
context = value;
RaisePropertyChanged("Context");
}
}
/// <summary>
/// Gets PageNavigation from Container
/// </summary>
public IPageNavigation PageNav
{
get
{
IPageNavigation pageNav =
(IPageNavigation)Container.Instance.Resolve(typeof(PageNavigation), "PageNavigation");
return pageNav;
}
}
}
}
@@ -14,6 +14,7 @@
DataContext="{Binding Source={x:Static vm:ViewModelLocatorTemplate.ViewModelNameStatic}}"
*/
using MyFriendsAround.WP7.Helpers.Navigation;
namespace MyFriendsAround.WP7.ViewModel
{
/// <summary>
@@ -55,81 +56,79 @@ namespace MyFriendsAround.WP7.ViewModel
/// </summary>
public class ViewModelLocator
{
private static MainViewModel _main;
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
////if (ViewModelBase.IsInDesignModeStatic)
////{
//// // Create design time view models
////}
////else
////{
//// // Create run time view models
////}
CreateMain();
}
/// <summary>
/// Gets the Main property.
/// </summary>
public static MainViewModel MainStatic
{
get
if (ViewModelBase.IsInDesignModeStatic)
{
if (_main == null)
{
CreateMain();
}
return _main;
// Create design time view models
}
else
{
//Register PageNavigation - only if not design time
Container.Instance.RegisterInstance(typeof(PageNavigation), "PageNavigation");
// Create run time view models
}
Container.Instance.RegisterInstance(typeof(MainViewModel), "MainViewModel");
Container.Instance.RegisterInstance(typeof(AboutViewModel), "AboutViewModel");
}
/// <summary>
/// Gets the Main property.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public MainViewModel Main
{
get
{
return MainStatic;
MainViewModel mainViewModel = GetViewModel<MainViewModel>();
return mainViewModel;
}
}
/// <summary>
/// Provides a deterministic way to delete the Main property.
/// Gets the About property.
/// </summary>
public static void ClearMain()
public AboutViewModel About
{
_main.Cleanup();
_main = null;
}
/// <summary>
/// Provides a deterministic way to create the Main property.
/// </summary>
public static void CreateMain()
{
if (_main == null)
get
{
_main = new MainViewModel();
AboutViewModel aboutViewModel = GetViewModel<AboutViewModel>();
return aboutViewModel;
}
}
/// <summary>
/// Cleans up all the resources.
/// </summary>
public static void Cleanup()
public void Cleanup()
{
ClearMain();
MainViewModel mainViewModel = GetViewModel<MainViewModel>();
mainViewModel.Cleanup();
AboutViewModel aboutViewModel = GetViewModel<AboutViewModel>();
aboutViewModel.Cleanup();
}
#region Local Helpers
private T GetViewModel<T>() where T : ViewModelBase
{
// Create a new view model
T vm = Container.Instance.Resolve<T>();
//Assign the Context from PageNavigation to Context property of the ViewModelBase
vm.Context = vm.PageNav.CurrentContext;
return vm;
}
#endregion
}
}
@@ -0,0 +1,35 @@
<phone:PhoneApplicationPage
x:Class="MyFriendsAround.WP7.Views.AboutPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
DataContext="{Binding About, Source={StaticResource Locator}}"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="{Binding Path=ApplicationTitle}" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="{Binding Path=PageName}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid>
</Grid>
</phone:PhoneApplicationPage>
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
namespace MyFriendsAround.WP7.Views
{
public partial class AboutPage : PhoneApplicationPage
{
public AboutPage()
{
InitializeComponent();
}
}
}
@@ -53,11 +53,6 @@
Grid.Row="1"
Margin="0,0,0,70">
<TextBlock Text="{Binding Welcome}"
Style="{StaticResource PhoneTextNormalStyle}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="40" />
<!--<Button Content="Publish"
HorizontalAlignment="Left" Margin="6,0,0,6" Name="btnPublishLocation"
Width="468"
@@ -104,7 +99,7 @@
<Preview:BindableApplicationBarIconButton Command="{Binding PublishLocationCommand}"
IconUri="/icons/appbar.publish.png"
Text="{Binding AppBarTextPublish}" />
<Preview:BindableApplicationBarIconButton Command="{Binding DisplayAboutCommand}"
<Preview:BindableApplicationBarIconButton Command="{Binding NavigateToAboutCommand}"
IconUri="/icons/appbar.questionmark.rest.png"
Text="{Binding AppBarTextAbout}" />