2017-11-24 11 views
0

MVVM 패턴이있는 ArcGIS Runtime .Net SDK 10.2.7을 사용하면 'System.NullReferenceException'이 표시됩니다. 의 생성자 :WPF MVVM을 올바르게 구현할 수 없습니다.

this.mapView.Map.Layers.Add (localTiledLayer);

이 샘플을 살펴보고 내가 뭘 잘못하고 있는지 알려주실 수 있습니까?

제가 가지고 것은 :

1- ViewModel.cs

public class ViewModel : INotifyPropertyChanged 
{ 
    private Model myModel = null; 
    private MapView mapView = null; 
    public event PropertyChangedEventHandler PropertyChanged; 
    public ViewModel() 
    { 
     var URI = "D:/GIS/Runtime/Tutorial/VanSchools.tpk"; 
     ArcGISLocalTiledLayer localTiledLayer = new ArcGISLocalTiledLayer(URI); 
     localTiledLayer.ID = "SF Basemap"; 
     localTiledLayer.InitializeAsync(); 

     this.mapView.Map.Layers.Add(localTiledLayer); 

    } 
    public string TilePackage 
    { 
     get { return this.myModel.TilePackage; } 
     set 
     { 
      this.myModel.TilePackage = value; 

     } 
    } 

2- Model.cs

public class Model 
{ 
    private string tilePackage = ""; 

    public Model() { } 

    public string TilePackage 
    { 
     get { return this.tilePackage; } 
     set 
     { 
      if (value != this.tilePackage) 
      { 
       this.tilePackage = value; 
      } 
     } 
    } 

-3- MainWindow.xaml

<Window x:Class="SimpleMVVM.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013" 
     xmlns:local="clr-namespace:SimpleMVVM" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 

     <Window.Resources> 
      <local:ViewModel x:Key="VM"/> 
     </Window.Resources> 

     <Grid DataContext="{StaticResource VM}"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="400" /> 
       <RowDefinition Height="200" /> 
      </Grid.RowDefinitions> 

      <esri:MapView x:Name="MyMapView" Grid.Row="0" 
         LayerLoaded="MyMapView_LayerLoaded" > 
       <esri:Map> </esri:Map> 
      </esri:MapView> 

     </Grid> 
</Window> 

4-

public partial class MainWindow : Window 
     { 
      public MainWindow() 
      { 
       InitializeComponent(); 
      } 

      private void MyMapView_LayerLoaded(object sender, LayerLoadedEventArgs e) 
      { 
       if (e.LoadError == null) 
        return; 

       Debug.WriteLine(string.Format("Error while loading layer : {0} - {1}", e.Layer.ID, e.LoadError.Message)); 
      } 

     } 

enter image description here

+0

지도보기에 대한 참조를 포함 할 수 없습니다 귀하의 뷰 모델 (또는 다른 시각 요소). MVVM 패턴으로 깨고 있습니다. 대신보기 모델에는지도 만 포함되어야하며지도를 XAML의 viewmodel의 Map 속성에 바인딩합니다. 업데이트 : 바로 Antti가 아래에 쓴 것을 정확히 깨달았습니다. 그게 "적절한"mvvm 방법입니다. – dotMorten

답변

2

그것은 문제처럼 보인다 MainWindow.xaml.csmapView가 개체의 인스턴스로 설정되지 않은 것입니다. 당신이 뭔가처럼 말을해야합니까 : 당신이 접선하지 않는 것 같다

this.mapView = new Mapview(); 
this.mapView.Map.Layers.Add(localTiledLayer); 
1

바인딩 그러나 일반적으로 당신이 당신의 ViewModel에서지도보기를 참조하지 말았어야 대신 MapView.Map을 결합해야한다. Map은 MapView의 모양을 정의하는 모델로 간주됩니다. 보기에

당신이 뭔가를 할 수있는 뷰 모델에서 다음 바인딩 설정

<Window.Resources> 
    <vm:MainViewModel x:Key="vm"></vm:MainViewModel> 
</Window.Resources> 
<Grid DataContext="{StaticResource vm}"> 
    <esri:MapView x:Name="MyMapView" 
        Map="{Binding Map}" 
        LayerLoaded="MyMapView_LayerLoaded"> 
    </esri:MapView> 
</Grid> 

이 있는지 확인

public class MainViewModel : INotifyPropertyChanged 
{ 
    public MainViewModel() 
    { 
     // Create map that is concidered to being a model that defines the content 
     // of the map 
     var map = new Map(); 
     // Add your layers to the map 
     var testServicePath = "https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"; 
     map.Layers.Add(new ArcGISTiledMapServiceLayer(new Uri(testServicePath))); 
     // map.Layers.Add(new ArcGISLocalTiledLayer("add your path here")); 
     Map = map; 
    } 

    private Map _map; 
    public Map Map 
    { 
     get 
     { 
      return _map; 
     } 
     set 
     { 
      _map = value; 
      NotifyPropertyChanged(nameof(Map)); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
}