I would like to use MVVM to show callouts.
I'm able to use code that Thad Tilton posted here in the Show Callout sample in the viewer.
It's not very pretty, but it works:

It doesn't use MVVM. Here's the code:
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">void</SPAN> <SPAN class="token function">Initialize</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
Basemap myBasemap <SPAN class="operator token">=</SPAN> Basemap<SPAN class="punctuation token">.</SPAN><SPAN class="token function">CreateStreets</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
Map myMap <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Map</SPAN><SPAN class="punctuation token">(</SPAN>myBasemap<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
MyMapView<SPAN class="punctuation token">.</SPAN>Map <SPAN class="operator token">=</SPAN> myMap<SPAN class="punctuation token">;</SPAN>
MyMapView<SPAN class="punctuation token">.</SPAN>GeoViewTapped <SPAN class="operator token">+</SPAN><SPAN class="operator token">=</SPAN> MyMapView_GeoViewTapped<SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">//this.DataContext = _vm;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">void</SPAN> <SPAN class="token function">MyMapView_GeoViewTapped</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">object</SPAN> sender<SPAN class="punctuation token">,</SPAN> esriCtrls<SPAN class="punctuation token">.</SPAN>GeoViewInputEventArgs e<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
MapPoint mapLocation <SPAN class="operator token">=</SPAN> e<SPAN class="punctuation token">.</SPAN>Location<SPAN class="punctuation token">;</SPAN>
Geometry myGeometry <SPAN class="operator token">=</SPAN> GeometryEngine<SPAN class="punctuation token">.</SPAN><SPAN class="token function">Project</SPAN><SPAN class="punctuation token">(</SPAN>mapLocation<SPAN class="punctuation token">,</SPAN> SpatialReferences<SPAN class="punctuation token">.</SPAN>Wgs84<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
MapPoint projectedLocation <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>MapPoint<SPAN class="punctuation token">)</SPAN>myGeometry<SPAN class="punctuation token">;</SPAN>
esriCtrls<SPAN class="punctuation token">.</SPAN>Callout c <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">esriCtrls<SPAN class="punctuation token">.</SPAN>Callout</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
Background <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">System<SPAN class="punctuation token">.</SPAN>Windows<SPAN class="punctuation token">.</SPAN>Media<SPAN class="punctuation token">.</SPAN>SolidColorBrush</SPAN><SPAN class="punctuation token">(</SPAN>System<SPAN class="punctuation token">.</SPAN>Windows<SPAN class="punctuation token">.</SPAN>Media<SPAN class="punctuation token">.</SPAN>Colors<SPAN class="punctuation token">.</SPAN>CornflowerBlue<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
BorderBrush <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">System<SPAN class="punctuation token">.</SPAN>Windows<SPAN class="punctuation token">.</SPAN>Media<SPAN class="punctuation token">.</SPAN>SolidColorBrush</SPAN><SPAN class="punctuation token">(</SPAN>System<SPAN class="punctuation token">.</SPAN>Windows<SPAN class="punctuation token">.</SPAN>Media<SPAN class="punctuation token">.</SPAN>Colors<SPAN class="punctuation token">.</SPAN>PaleVioletRed<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
BorderThickness <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">System<SPAN class="punctuation token">.</SPAN>Windows<SPAN class="punctuation token">.</SPAN>Thickness</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="number token">5</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">5</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">5</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">3</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
Content <SPAN class="operator token">=</SPAN> $<SPAN class="string token">"Lat: {projectedLocation.Y:F3} Long:{projectedLocation.X:F3}"</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">;</SPAN>
GeoView<SPAN class="punctuation token">.</SPAN><SPAN class="token function">SetViewOverlayAnchor</SPAN><SPAN class="punctuation token">(</SPAN>c<SPAN class="punctuation token">,</SPAN> e<SPAN class="punctuation token">.</SPAN>Location<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
MyMapView<SPAN class="punctuation token">.</SPAN>Overlays<SPAN class="punctuation token">.</SPAN>Items<SPAN class="punctuation token">.</SPAN><SPAN class="token function">Add</SPAN><SPAN class="punctuation token">(</SPAN>c<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">//_vm.MyCallouts.Add(c);</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>This is where I get lost, this xaml compiles:
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"><</SPAN>Grid</SPAN><SPAN class="punctuation token">></SPAN></SPAN>
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"><</SPAN><SPAN class="namespace token">esri:</SPAN>MapView</SPAN> <SPAN class="attr-name token"><SPAN class="namespace token">x:</SPAN>Name</SPAN><SPAN class="attr-value token"><SPAN class="punctuation token">=</SPAN><SPAN class="punctuation token">"</SPAN>MyMapView<SPAN class="punctuation token">"</SPAN></SPAN><SPAN class="punctuation token">></SPAN></SPAN>
<esri:MapView.Overlays>
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"><</SPAN><SPAN class="namespace token">esri:</SPAN>OverlayItemsControl</SPAN> <SPAN class="attr-name token">ItemsSource</SPAN><SPAN class="attr-value token"><SPAN class="punctuation token">=</SPAN><SPAN class="punctuation token">"</SPAN>{Binding MyOverlays}<SPAN class="punctuation token">"</SPAN></SPAN><SPAN class="punctuation token">/></SPAN></SPAN>
</esri:MapView.Overlays>
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"></</SPAN><SPAN class="namespace token">esri:</SPAN>MapView</SPAN><SPAN class="punctuation token">></SPAN></SPAN>
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"><</SPAN>Border</SPAN><SPAN class="style-attr language-css token"><SPAN class="attr-name token"> <SPAN class="attr-name token">Style</SPAN></SPAN><SPAN class="punctuation token">="</SPAN><SPAN class="attr-value token"><SPAN class="punctuation token">{</SPAN>StaticResource BorderStyle<SPAN class="punctuation token">}</SPAN></SPAN><SPAN class="punctuation token">"</SPAN></SPAN><SPAN class="punctuation token">></SPAN></SPAN>
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"><</SPAN>TextBlock</SPAN> <SPAN class="attr-name token">Text</SPAN><SPAN class="attr-value token"><SPAN class="punctuation token">=</SPAN><SPAN class="punctuation token">"</SPAN>Tap to show a callout.<SPAN class="punctuation token">"</SPAN></SPAN>
<SPAN class="attr-name token">FontWeight</SPAN><SPAN class="attr-value token"><SPAN class="punctuation token">=</SPAN><SPAN class="punctuation token">"</SPAN>SemiBold<SPAN class="punctuation token">"</SPAN></SPAN>
<SPAN class="attr-name token">TextAlignment</SPAN><SPAN class="attr-value token"><SPAN class="punctuation token">=</SPAN><SPAN class="punctuation token">"</SPAN>Center<SPAN class="punctuation token">"</SPAN></SPAN> <SPAN class="punctuation token">/></SPAN></SPAN>
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"></</SPAN>Border</SPAN><SPAN class="punctuation token">></SPAN></SPAN>
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"></</SPAN>Grid</SPAN><SPAN class="punctuation token">></SPAN></SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>Here's my viewmodel (PropertyChangedBase implements INotifyPropertyChanged):
<SPAN class="keyword token">public</SPAN> <SPAN class="keyword token">class</SPAN> <SPAN class="token class-name">MyVM</SPAN><SPAN class="punctuation token">:</SPAN> PropertyChangedBase
<SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">public</SPAN> ObservableCollection<SPAN class="operator token"><</SPAN>esriCtrls<SPAN class="punctuation token">.</SPAN>Callout<SPAN class="operator token">></SPAN> MyCallouts <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">get</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">set</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="operator token">=</SPAN>
<SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">ObservableCollection</SPAN><SPAN class="operator token"><</SPAN>esriCtrls<SPAN class="punctuation token">.</SPAN>Callout<SPAN class="operator token">></SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">public</SPAN> <SPAN class="token function">MyVM</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>Uncommented/commented code to use vm:
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">void</SPAN> <SPAN class="token function">Initialize</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
Basemap myBasemap <SPAN class="operator token">=</SPAN> Basemap<SPAN class="punctuation token">.</SPAN><SPAN class="token function">CreateStreets</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
Map myMap <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Map</SPAN><SPAN class="punctuation token">(</SPAN>myBasemap<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
MyMapView<SPAN class="punctuation token">.</SPAN>Map <SPAN class="operator token">=</SPAN> myMap<SPAN class="punctuation token">;</SPAN>
MyMapView<SPAN class="punctuation token">.</SPAN>GeoViewTapped <SPAN class="operator token">+</SPAN><SPAN class="operator token">=</SPAN> MyMapView_GeoViewTapped<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">this</SPAN><SPAN class="punctuation token">.</SPAN>DataContext <SPAN class="operator token">=</SPAN> _vm<SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">void</SPAN> <SPAN class="token function">MyMapView_GeoViewTapped</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">object</SPAN> sender<SPAN class="punctuation token">,</SPAN> esriCtrls<SPAN class="punctuation token">.</SPAN>GeoViewInputEventArgs e<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
MapPoint mapLocation <SPAN class="operator token">=</SPAN> e<SPAN class="punctuation token">.</SPAN>Location<SPAN class="punctuation token">;</SPAN>
Geometry myGeometry <SPAN class="operator token">=</SPAN> GeometryEngine<SPAN class="punctuation token">.</SPAN><SPAN class="token function">Project</SPAN><SPAN class="punctuation token">(</SPAN>mapLocation<SPAN class="punctuation token">,</SPAN> SpatialReferences<SPAN class="punctuation token">.</SPAN>Wgs84<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
MapPoint projectedLocation <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>MapPoint<SPAN class="punctuation token">)</SPAN>myGeometry<SPAN class="punctuation token">;</SPAN>
esriCtrls<SPAN class="punctuation token">.</SPAN>Callout c <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">esriCtrls<SPAN class="punctuation token">.</SPAN>Callout</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
Background <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">System<SPAN class="punctuation token">.</SPAN>Windows<SPAN class="punctuation token">.</SPAN>Media<SPAN class="punctuation token">.</SPAN>SolidColorBrush</SPAN><SPAN class="punctuation token">(</SPAN>System<SPAN class="punctuation token">.</SPAN>Windows<SPAN class="punctuation token">.</SPAN>Media<SPAN class="punctuation token">.</SPAN>Colors<SPAN class="punctuation token">.</SPAN>CornflowerBlue<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
BorderBrush <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">System<SPAN class="punctuation token">.</SPAN>Windows<SPAN class="punctuation token">.</SPAN>Media<SPAN class="punctuation token">.</SPAN>SolidColorBrush</SPAN><SPAN class="punctuation token">(</SPAN>System<SPAN class="punctuation token">.</SPAN>Windows<SPAN class="punctuation token">.</SPAN>Media<SPAN class="punctuation token">.</SPAN>Colors<SPAN class="punctuation token">.</SPAN>PaleVioletRed<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
BorderThickness <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">System<SPAN class="punctuation token">.</SPAN>Windows<SPAN class="punctuation token">.</SPAN>Thickness</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="number token">5</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">5</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">5</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">3</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN>
Content <SPAN class="operator token">=</SPAN> $<SPAN class="string token">"Lat: {projectedLocation.Y:F3} Long:{projectedLocation.X:F3}"</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">;</SPAN>
GeoView<SPAN class="punctuation token">.</SPAN><SPAN class="token function">SetViewOverlayAnchor</SPAN><SPAN class="punctuation token">(</SPAN>c<SPAN class="punctuation token">,</SPAN> e<SPAN class="punctuation token">.</SPAN>Location<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">//MyMapView.Overlays.Items.Add(c);</SPAN>
_vm<SPAN class="punctuation token">.</SPAN>MyCallouts<SPAN class="punctuation token">.</SPAN><SPAN class="token function">Add</SPAN><SPAN class="punctuation token">(</SPAN>c<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>I get a run-time error before I even tap on the screen:
System.Windows.Data Error: 2 :
Cannot find governing FrameworkElement or FrameworkContentElement for target element.
BindingExpression:Path=MyOverlays; DataItem=null;
target element is 'OverlayItemsControl' (HashCode=19513753);
target property is 'ItemsSource' (type 'IEnumerable')
With this xaml also fails:
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"><</SPAN><SPAN class="namespace token">esri:</SPAN>MapView</SPAN> <SPAN class="attr-name token"><SPAN class="namespace token">x:</SPAN>Name</SPAN><SPAN class="attr-value token"><SPAN class="punctuation token">=</SPAN><SPAN class="punctuation token">"</SPAN>MyMapView<SPAN class="punctuation token">"</SPAN></SPAN><SPAN class="punctuation token">></SPAN></SPAN>
<esri:MapView.Overlays>
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"><</SPAN><SPAN class="namespace token">esri:</SPAN>OverlayItemsControl</SPAN>
<SPAN class="attr-name token">ItemsSource</SPAN><SPAN class="attr-value token"><SPAN class="punctuation token">=</SPAN><SPAN class="punctuation token">"</SPAN>{Binding Path<SPAN class="punctuation token">=</SPAN>DataContext.MyOverlays, RelativeSource<SPAN class="punctuation token">=</SPAN>{RelativeSource AncestorType<SPAN class="punctuation token">=</SPAN>{x:Type esri:MapView}}}<SPAN class="punctuation token">"</SPAN></SPAN><SPAN class="punctuation token">/></SPAN></SPAN>
</esri:MapView.Overlays>
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"></</SPAN><SPAN class="namespace token">esri:</SPAN>MapView</SPAN><SPAN class="punctuation token">></SPAN></SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>But with a different error:
System.Windows.Data Error: 4 : Cannot find source for binding with reference
'RelativeSource FindAncestor, AncestorType='Esri.ArcGISRuntime.UI.Controls.MapView', AncestorLevel='1''.
BindingExpression:Path=DataContext.MyOverlays; DataItem=null;
target element is 'OverlayItemsControl' (HashCode=16581154);
target property is 'ItemsSource' (type 'IEnumerable')
Looking at the live visual tree on the version that works (with no mvvm), I see the callout textbox under the mapview:

Any clues or suggestions are greatly appreciated!