I use a different approach and is based on the idea that one may want to manage drawing in a view other than the main view. I believe the approach from @JenniferNery would only work in the view model tied to the view that contains MapView. There is also an assumption that a library which provides event aggregation is being used (e.g., MVVMLight although I use Prism). One might argue is more complex, but I believe it offers a way to provide a true MVVM solution in a complex application that can go beyond a single view.
I have a custom MapView control, which has it's own ViewModel. My Xaml (with only the relevant pieces) looks like this
<esri:MapView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="http://prismlibrary.com"
xmlns:esri="clr-namespace:Esri.ArcGISRuntime.Xamarin.Forms;assembly=Esri.ArcGISRuntime.Xamarin.Forms"
xmlns:behaviors="clr-namespace:Mobile.AsBuilt.Framework.MapView.Behaviors;assembly=Mobile.AsBuilt.Framework"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="Mobile.AsBuilt.Framework.MapView.MapViewControl"
x:Name="mapView"
Map="{Binding Map}"
SketchEditor="{Binding SketchEditor}"
GraphicsOverlays="{Binding GraphicsOverlays}"
</esri:MapView>
In the supporting ViewModel I inject the IEventAggregator, also one thing I found is that the bound SketchEditor needs to be initialized in the constructor .
public MapViewControlViewModel(IEventAggregator eventAggregator, ...)
{
eventAggregator.GetEvent<MapLoadedEvent>().Subscribe(OnMapLoaded);
EventAggregator = eventAggregator;
SketchEditor = new SketchEditor();
}
The idea now is that the SketchEditor will be sent out to the rest of the application by publishing an event. There is one other caveat, and that is we can not send off our SketchEditor until the map in initialized.
So we need a couple events. One event that can be published to the application to indicate the Map is loaded (MapLoadedEvent), and another that can send the SketchEditor out (SketchEditorInitializedEvent). We put a handler for our MapLoaded event in the MapViewControlViewModel and then in our handler publish out the SketchEditorInitializedEvent
private void OnMapLoaded(MapLoadedEventArgs obj)
{
try
{
Map = obj.Map;
EventAggregator.GetEvent<SketchEditorInitializedEvent>().Publish(SketchEditor);
}
catch (Exception e)
{
Log.Error(e, e.Message);
}
}
Now anywhere I need the SketchEditor I can handle this event
protected EditBaseViewModel(IEventAggregator eventAggregator...) : base(eventAggregator)
{
SubscriptionTokens.Add(EventAggregator.GetEvent<SketchEditorInitializedEvent>().Subscribe(se => SketchEditor = se));
}
This will then support a modular application with the ability to draw from any ViewModel that provides this functionality
Thanks,
-Joe