GeoLocationViewModel Class
The GeoLocationViewModel.Start
method instantiates either the GeolocatorProxy
or a MockGeoLocator
depending on the value of the viewmodel’s Boolean useMockLocator
field (see Listing 1).
Tip
Rather than requiring the viewmodel to determine which IGeoLocator
implementation it should use, Inversion of Control (IoC) could be employed to resolve the object.
The Start
method subscribes to the PositionChanged
and StatusChanged
events of the IGeoLocator
, and then calls the IGeoLocator
object’s Start
method to begin receiving location notifications.
When the PositionChanged
event is raised, the viewmodel’s GeoCoordinate
property is set to the current location.
LISTING 1. GeoLocationViewModel.Start
Method (excerpt)
void Start()
{
if (running)
{
return;
}
Running = true;
CanStart = false;
if (useMockLocator)
{
geoLocator = new MockGeoLocator();
}
else
{
geoLocator = new GeolocatorProxy
{
MovementThreshold = 20,
DesiredAccuracy = PositionAccuracy.High,
ReportInterval = 1000
};
}
...
geoLocator.PositionChanged
+= (o, args) =>
{
GeoCoordinate coordinate = args.Position.GeoCoordinate;
GeoCoordinate = coordinate;
ResolveAddress(coordinate);
};
geoLocator.StatusChanged
+= (o, args) => PositionStatus = args.Status;
geoLocator.Start();
}
The viewmodel contains two DelegateCommands
that are used to start and stop position monitoring. The commands are initialized in the viewmodel constructor, as shown:
public GeoLocationViewModel()
{
startCommand = new DelegateCommand(obj => Start(), arg => CanStart);
stopCommand = new DelegateCommand(obj => Stop(), arg => Running);
PropertyChanged += delegate { RefreshCommands(); };
}
Tapping the Stop button causes the viewmodel’s StopCommand
to execute, which calls the Stop
method of the geoLocator
. This prevents the PositionChanged
event from being raised. The Stop
method is shown in the following excerpt:
void Stop()
{
if (!running || geoPositionWatcher == null)
{
return;
}
if (sampler != null)
{
sampler.Dispose();
sampler = null;
}
geoPositionWatcher.Stop();
Running = false;
CanStart = true;
}