Introduction
The Cimbalino Windows Phone Toolkit delivers a set of useful and powerful MVVM-compatible tools and services to help developers build Silverlight applications for Windows Phone. The Toolkit is divided in projects that deliver various features, ranging from base MVVM services and helpers, through to code for background agents and for accessing media library, location services and so on. Cimbalino.Phone.Toolkit.Location is a MVVM compatible services for location access.
ILocationService represents an interface for a service capable of handling the device location capabilities. The implementation is: LocationService.
Building the example code
The source code for the code example is available here: Location Sample (Github).
To build the source code you will also need the MVVM Light Toolkit and the Cimbalino Windows Phone Toolkit. Their packages are available in the Nuget Package Manager.
Note: you must specify the following capabilities in the app manifest: ID_CAP_LOCATION.
Registering the service
Register the service in the ViewModelLocator constructor as shown below:
-
-
- public class ViewModelLocator
- {
-
- public ViewModelLocator()
- {
- ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
- if (!SimpleIoc.Default.IsRegistered<ILocationService>())
- {
- SimpleIoc.Default.Register<ILocationService, LocationService>();
- }
- SimpleIoc.Default.Register<MainViewModel>();
- }
-
-
-
- public MainViewModel MainViewModel
- {
- get
- {
- return ServiceLocator.Current.GetInstance<MainViewModel>();
- }
- }
-
- public static void Cleanup()
- {
-
- var viewModelLocator = (ViewModelLocator)App.Current.Resources["Locator"];
- viewModelLocator.MainViewModel.Cleanup();
- }
- }
Implementing the ViewModel
Then we should implement the
MainViewModel class as in the following:
- using System.Windows;
- using System.Windows.Input;
- using System.Windows.Threading;
-
- using Cimbalino.Phone.Toolkit.Services;
-
- using GalaSoft.MvvmLight.Command;
- using GalaSoft.MvvmLight;
-
-
- public class MainViewModel : ViewModelBase
- {
-
- private readonly ILocationService _locationService;
-
- private bool _isLocationEnable;
-
-
- private bool _isStartEnable;
-
-
- private bool _isStopEnable;
-
-
- private double _latitude;
-
-
- private double _longitude;
-
-
- private LocationServiceStatus _status;
-
-
- public MainViewModel(ILocationService locationService)
- {
- IsStartEnable = true;
- IsLocationEnable = true;
- IsStopEnable = false;
- _locationService = locationService;
- _locationService.ReportInterval = 5;
- _locationService.PositionChanged += LocationService_PositionChanged;
- _locationService.StatusChanged += LocationService_StatusChanged;
- StartCommand =new RelayCommand(Start);
- StopCommand =new RelayCommand(Stop);
- LocationCommand = new RelayCommand(GetLocation);
- }
-
-
- public bool IsLocationEnable
- {
- get
- {
- return this._isLocationEnable;
- }
- set
- {
- Set("IsLocationEnable", ref _isLocationEnable, value);
- }
- }
-
-
-
- public bool IsStartEnable
- {
- get
- {
- return this._isStartEnable;
- }
- set
- {
- Set("IsStartEnable", ref _isStartEnable, value);
- }
- }
-
-
- public bool IsStopEnable
- {
- get
- {
- return this._isStopEnable;
- }
- set
- {
- Set("IsStopEnable", ref _isStopEnable, value);
- }
- }
-
-
- public double Latitude
- {
- get
- {
- return _latitude;
- }
- set
- {
- Set("Latitude", ref _latitude, value);
- }
- }
-
-
- public ICommand LocationCommand { get; private set; }
-
-
- public double Longitude
- {
- get
- {
- return this._longitude;
- }
- set
- {
- Set("Longitude", ref _longitude, value);
- }
- }
-
-
- public ICommand StartCommand { get; private set; }
-
-
- public LocationServiceStatus Status
- {
- get
- {
- return _status;
- }
- set
- {
- Set("Status", ref _status, value);
- }
- }
-
-
- public ICommand StopCommand { get; private set; }
-
-
- public override void Cleanup()
- {
- base.Cleanup();
- _locationService.PositionChanged -= LocationService_PositionChanged;
- _locationService.StatusChanged -= LocationService_StatusChanged;
- }
-
-
- private async void GetLocation()
- {
- var result = await _locationService.GetPositionAsync();
- Longitude = result.Longitude;
- Latitude = result.Latitude;
- }
-
-
- private void LocationService_PositionChanged(object sender, LocationServicePositionChangedEventArgs e)
- {
- Deployment.Current.Dispatcher.BeginInvoke(delegate
- {
- Latitude = e.Position.Latitude;
- Longitude = e.Position.Longitude;
- });
- }
-
-
- private void LocationService_StatusChanged(object sender, LocationServiceStatusChangedEventArgs e)
- {
- Deployment.Current.Dispatcher.BeginInvoke(delegate { Status = e.Status; });
- }
-
-
- private void Start()
- {
- IsStartEnable = false;
- IsStopEnable = true;
- IsLocationEnable = false;
- _locationService.Start();
- }
-
-
- private void Stop()
- {
- IsLocationEnable = true;
- IsStartEnable = true;
- IsStopEnable = false;
- _locationService.Stop();
- }
- }
Implementing the View
Add the binding in the main page is like:
- DataContext="{Binding MainViewModel, Source={StaticResource Locator}}"
-
- The MainPage.xaml can be the following:
- <phone:PhoneApplicationPage x:Class="CimbalinoSample.MainPage"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- DataContext="{Binding MainViewModel,
- Source={StaticResource Locator}}"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- Orientation="Portrait"
- SupportedOrientations="Portrait"
- shell:SystemTray.IsVisible="True"
- mc:Ignorable="d">
-
- <!-- 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 Margin="12,0"
- Style="{StaticResource PhoneTextTitle2Style}"
- Text="Cimbalino Sample" />
- <TextBlock Margin="9,-7,0,0"
- Style="{StaticResource PhoneTextTitle1Style}"
- Text="Location" />
- </StackPanel>
-
- <!-- ContentPanel - place additional content here -->
- <Grid x:Name="ContentPanel"
- Grid.Row="1"
- Margin="12,0,12,0">
- <TextBlock TextWrapping="Wrap">
- Latitude:<Run Text="{Binding Latitude}" />
- </TextBlock>
- <TextBlock Margin="0,51,0,-51" TextWrapping="Wrap">
- Logitude:<Run Text="{Binding Longitude}" />
- </TextBlock>
- <TextBlock Margin="0,102,0,-102" TextWrapping="Wrap">
- Status:<Run Text="{Binding Status}" />
- </TextBlock>
- <Button Margin="0,298,0,214"
- IsEnabled="{Binding IsStartEnable}"
- Command="{Binding StartCommand}"
- Content="Start" />
- <Button Height="76"
- IsEnabled="{Binding IsStopEnable}"
- Margin="0,0,0,138"
- VerticalAlignment="Bottom"
- Command="{Binding StopCommand}"
- Content="Stop" />
- <Button Margin="0,219,0,293"
- IsEnabled="{Binding IsLocationEnable}"
- Command="{Binding LocationCommand}"
- Content="Get location" />
- </Grid>
- </Grid>
- </phone:PhoneApplicationPage>