Select to view content in your preferred language

Binding Layers of Map within Prism (MVVM)

3010
4
Jump to solution
06-11-2012 08:04 AM
DaviKucharski
Deactivated User
Hello,

I am having an issue binding the Layers object to my Map object. I have looked over a few other posts and try to re-create their fixes but cannot. I do not get an error, I just do not get a map visually displayed. Here are some of my code snippets. Can anyone see what I am doing wrong. Just to be clear:

1. My xaml has a map object with a Layers attribute with Binding.
2. My xaml.cs Initializes the component and then sets the DataContext
3. My ViewModel code, sets the view, runs the CreateMapLayers function that sets the BaseMapLayerService public property (this is the property that the Layers is bound to in xaml).

xaml:
<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"                x:Class="Geomentum.MediaReach.Modules.Map.View.MapView"     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"     mc:Ignorable="d"      xmlns:esri="http://schemas.esri.com/arcgis/client/2009"     xmlns:local="clr-namespace:Geomentum.MediaReach.Modules.Map.View"     xmlns:ViewModel="clr-namespace:Geomentum.MediaReach.Modules.Map.ViewModel">         <esri:Map x:Name="MyMap" WrapAround="True" IsLogoVisible="False" Layers="{Binding ViewModel.BaseMapLayerService}" /> </UserControl>


xaml.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Geomentum.MediaReach.Modules.Map.ViewModel;  namespace Geomentum.MediaReach.Modules.Map.View {     public partial class MapView : UserControl, IMapView      {         public MapView()         {             InitializeComponent();         }          #region IMapView Members         public IMapViewModel Model         {             get             {                 return this.DataContext as MapViewModel;             }             set             {                 this.DataContext = value;             }         }         #endregion     } }


MapViewModel.cs:
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Geomentum.MediaReach.Modules.Map.View; using Microsoft.Practices.Prism.Events; using System.ComponentModel; using System.Collections.Generic; using Geomentum.MediaReach.Infrastructure.Models;   namespace Geomentum.MediaReach.Modules.Map.ViewModel {     public class MapViewModel : IMapViewModel, INotifyPropertyChanged      {         private readonly IEventAggregator eventAggregator;         private ESRI.ArcGIS.Client.LayerCollection _baseMapLayerService;         public IMapView View { get; set; }          public MapViewModel(IMapView view, IEventAggregator eventAggregator, MediaReachMap map)         {             View = view;             View.Model = this;              BaseMapLayerService = CreateMapLayers();             this.eventAggregator = eventAggregator;         }          public ESRI.ArcGIS.Client.LayerCollection BaseMapLayerService         {             get { return this._baseMapLayerService; }             set             {                 this._baseMapLayerService = value;                 OnPropertyChanged("BaseMapLayerService");             }         }          private ESRI.ArcGIS.Client.LayerCollection CreateMapLayers()         {             ESRI.ArcGIS.Client.LayerCollection layers = new ESRI.ArcGIS.Client.LayerCollection();              //create the base map layer             ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer baseLayer = new ESRI.ArcGIS.Client.ArcGISDynamicMapServiceLayer()             {                 ID = "BaseLayer",                 Url = "http://dg2k8esridev1/ArcGISDevelopment/rest/services/BaseMap/MapServer"             };             layers.Add(baseLayer);              return layers;         }          #region INotifyPropertyChanged Members         public event PropertyChangedEventHandler PropertyChanged;         private void OnPropertyChanged(string propertyName)         {             PropertyChangedEventHandler handler = this.PropertyChanged;             if (handler != null)             {                 handler(this, new PropertyChangedEventArgs(propertyName));             }         }         #endregion     } }
0 Kudos
1 Solution

Accepted Solutions
JoeHershman
MVP Alum
Your Layers binding needs to have Mode=TwoWay added to the Binding statement is one thing I notice.  Also your ViewModel is your DataContext so I do not think you want the Binding to have ViewModel in there.  I think this would do it

    Layers="{Binding BaseMapLayerService, Mode=TwoWay}


Hope that helps
-Joe
Thanks,
-Joe

View solution in original post

0 Kudos
4 Replies
JoeHershman
MVP Alum
Your Layers binding needs to have Mode=TwoWay added to the Binding statement is one thing I notice.  Also your ViewModel is your DataContext so I do not think you want the Binding to have ViewModel in there.  I think this would do it

    Layers="{Binding BaseMapLayerService, Mode=TwoWay}


Hope that helps
-Joe
Thanks,
-Joe
0 Kudos
JenniferNery
Esri Regular Contributor
I did some shortcut here but I can bind to Map.Layers just by setting UserControl.DataContext
<UserControl x:Class="Forum.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:esri="http://schemas.esri.com/arcgis/client/2009">

    <Grid x:Name="LayoutRoot" Background="White">
  <esri:Map WrapAround="True" x:Name="MyMap" Layers="{Binding Layers}"/>   
 </Grid>
</UserControl>



 public partial class MainPage : UserControl
 {
  public MainPage()
  {
   InitializeComponent();
   this.DataContext = new Model();   
  }

  public class Model
  {
   public Model()
   {
    Layers = new LayerCollection();
    Layers.Add(new ArcGISTiledMapServiceLayer() { Url = "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" });
   }
   public LayerCollection Layers { get; set; }
  }
 }
0 Kudos
DaviKucharski
Deactivated User
Jennifer and Joe,

Thanks. Both worked.
0 Kudos
JoeHershman
MVP Alum
Jennifer and Joe,

Thanks. Both worked.


Your welcome if you could mark as answered that would be great.

Not sure how far along you are with developing in PRISM.  What I have found is that a reference to the Map object itself within ViewModels is really necessary because there are a lot of properties and methods that the Map exposes that are pretty important throughout the application.  I have my MainPage implement an Interface which exposes the Map and use Dependency Injection to pass that Interface object instance to ViewModels across an application

The manipulation of the Layers would be pretty much the same as how you are doing it except it is with the Map::Layers collection not a LayerCollection object.

Good luck,
-Joe
Thanks,
-Joe
0 Kudos