I have a page (view) in my Windows Phone 7 application that uses the Silverlight Map control.
I need to call the SetView method on the control, but I'd like to stick to the MVVM style of keeping functionality in the view model.
I plan to call this method after clicking on an application bar button, so I don't have access to the Map via the EventArgs parameter.
What's the best way to do this?
I haven't worked with the map control myself, but here's a couple of ideas off of the top of my head:
You could publish an event using the IEventAggregator which the view could be subscribed to and use to call SetView.
You could implement a custom IResult which uses the ActionExecutionContext to get the view, find the map control and call SetView on it.
You could implement IViewAware on your view model (or override OnViewLoaded if you inherit from Screen) and follow a more Supervising Controller approach by interacting with the view through an interface to call SetView.
I've done this by having a MapLocation property on the view model, and then hooking up to the view model's PropertyChanged event in the view. When the property is the MapLocation property, I just call SetView and pass in the value of the ViewModel's MapLocation property.
I know it's not "strictly" MVVM, but what we're talking about here is something that is view specific, but can't be bound to. The event aggregator approach as Rob suggests is another good option, but seems like overkill in this scenario. I'm all for going with whatever works well and with good performance for the user :)
I did a lot of research on this particular thing and this question was helpful. Ultimately I ended up creating a Microsoft.Phone.Controls.Maps.Map Property on my ViewModel. All I had to do was set the x:Name property in the xaml to the Name of the Property that was the Map on the view model. Then I could easily update the map from the view model, and call SetView. You can easily alter the center of the map and change the zoom level just by changing those properties of the map, so you really only need to call SetView on initialization. I believe you can bind just about anything using the similar technique. The Map control is pretty awesome for an out of the box control, and plays very nicely with Caliburn.Micro.