2017-11-24 2 views
0

ArcGIS Runtime .Net SDK 10.2.7をMVVMパターンで使用しています。私は'System.NullReferenceException'を取得しています。 ViewModelコンストラクタ中で: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- MainWindow.xaml.cs

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

のMapViewへの参照を含めることはできませんあなたのビューモデル(または他の視覚的要素)。それはMVVMのパターンで壊れています。代わりに、あなたのviewmodelにマップのみが含まれていて、XAMLのviewmodelのMapプロパティにマップをバインドします。アップデート:ちょうどそれがAnttiが以下に書いたものだと分かりました。それはそれを行う "適切な" mvvmの方法です – dotMorten

答えて

2

問題はmapViewがオブジェクトのインスタンスに設定されていないということであるように見えます。あなたが何かのように言う必要があるん:あなたがフックアップされていないようだ

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

結合が、一般的に、あなたのViewModelからのMapViewへの参照を持つべきではありません、代わりにMapView.Mapをバインドする必要があります。 Mapは、MapViewの外観を定義するモデルとみなされます。あなたのビューで

あなたはこのような何かを行うことができ、あなたのViewModelに続いて結合セットアップ

<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)); 
     } 
    } 
} 
関連する問題