很长一段时间以来,我一直在努力了解在n MVVM场景中处理bing Maps的正确方法。
我可以在我的XAML视图中创建一个这样的地图:
<map:Map x:Name="MyMap"
Credentials="MySuperSecretCredentials"/>
我的代码隐藏文件我可以轻松地与地图互动,例如:
private async void FindMe_Clicked()
{
_cts = new CancellationTokenSource();
CancellationToken token = _cts.Token;
// Get the location.
Geoposition pos = await _geolocator.GetGeopositionAsync().AsTask(token);
MyMap.SetView(new BasicGeoposition() { Latitude = pos.Coordinate.Latitude, Longitude = pos.Coordinate.Longitude }, 15);
}
只需引用MyMap,我们就可以在后面的代码中用它做任何我喜欢的事情。 但是如何执行相同的命令我的viewModel?
我想我应该从使用调用viewModel上的方法的命令替换FindMe_Clicked
开始?并且让该方法执行类似于代码隐藏中的方法。但是我如何在viewModel中访问MyMap
?
也许我的VM看起来像这样:
public class MainViewModel
{
public RelayCommand GetLocation { get; private set; }
public MainViewModel()
{
this.GetLocation = new RelayCommand(this.FindMe());
}
public void FindMe()
{
_cts = new CancellationTokenSource();
CancellationToken token = _cts.Token;
// Get the location.
Geoposition pos = await _geolocator.GetGeopositionAsync().AsTask(token);
MyMap.SetView(new BasicGeoposition() { Latitude = pos.Coordinate.Latitude, Longitude = pos.Coordinate.Longitude }, 15);
}
}
如果我没有考虑这个问题,那么我需要做的就是将视图中存在的MyMap
的同一个实例以某种方式传递给我的viewmodel?
对此的帮助表示赞赏,我也很想看到如何使用bibg map我可移植类库的任何示例,或者如果有人在某个地方遇到它,我会看到一个Mvvm模式。谢谢!
答案 0 :(得分:0)
在遵循MVVM模式时,不应尝试从Viewmodel中访问 View 图层的元素(例如地图控件)。相反,您(理论上)创建了两个公共属性CenterLatitude
和CenterLongitude
,并在XAML代码中直接将它们绑定到maps控件:
<Map Credentials="MySuperSecretCredentials" ZoomLevel="15">
<Map.Center>
<Location Latitude="{Binding CenterLatitude}" Longitude="{Binding CenterLongitude}"/>
</Map.Center>
</Map>
在Viewmodel中设置方法FindMe
是可以的,但不是从MyMap
控件访问并从那里调用SetView(...)
,而是只更新两个属性{{ 1}}和CenterLatitude
并确保引发CenterLongitude
事件,以便通知View有关已更改的数据并自行更新。
但是很遗憾,bing地图控件的PropertyChanged
属性不支持数据绑定 - 出于性能原因,Microsoft似乎故意关闭此功能。如果您仍想保留MVVM模式,请查看this article I've written some time ago,了解如何规避此限制。
(根据我的经验,这种解决方法效果很好,并且不会影响性能。只需确保不要经常更新Center
属性,这意味着每秒几次......)