Select to view content in your preferred language

LayerCollection and MVVM

2268
2
04-27-2011 07:25 AM
AndrewMurdoch
Regular Contributor
I'm trying to use an MVVM framework to update the map's basemap layer via a bound Map:Layers property.  I can update the Layers property through code-behind, but I'm so far unable to get the basemap layer to update when using the MVVM framework. 

Can you take a look and see if you can tell me what I'm doing wrong (or if this is possible)?

Below is the code I'm attempting to use.

First the XAML map binding (I've already set a reference to my view model in Resources):

        <esri:Map x:Name="myMap" Grid.Row="0" Extent="-160,15,-75,80" Layers="{Binding Source={StaticResource myViewModel}, Path=MyLayers,Mode=TwoWay}">


Next the property that I'm attempting to bind to:

        private LayerCollection _myLayers = new LayerCollection();
        public LayerCollection MyLayers
        {
            get { return _myLayers; }
            set 
            {
                if (!object.ReferenceEquals(_myLayers, value))
                {
                    _myLayers = value;
                    OnPropertyChanged("MyLayers");
                }
            }
        }


Finally the code that updates the MyLayers property:

                ArcGISTiledMapServiceLayer tempBaseLayer = new ArcGISTiledMapServiceLayer();
                 tempBaseLayer.Url = "http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer";

                LayerCollection tempLayerCollection = new LayerCollection();
                tempLayerCollection.Add(tempBaseLayer);
                MyLayers = tempLayerCollection;


Thanks,
Andrew
0 Kudos
2 Replies
LisaChesley
Emerging Contributor
Good afternoon, Andrew!

What you're attempting to do is absolutely possible.  Your code looks fine to me, but for comparison purposes, here is how I've done it (quite similar), with explanations about what code I've used where.

First, the XAML (I've called mine MapView.xaml):

<esri:Map x:Name="map" Background="White" IsLogoVisible="False" Layers="{Binding MapLayerCollection}" viewModels:MapViewModel.BindableExtent="{Binding MapExtent}" >


MapLayerCollection is a property on my view model, set up as below (in MapViewModel):

private LayerCollection mapLayerCollection;

public LayerCollection MapLayerCollection
        {
            get { return mapLayerCollection; }
            set
            {
                if (mapLayerCollection != value)
                {
                    mapLayerCollection = value;
                    RaisePropertyChanged("LayerCollection");
                }
            }
        }        


In the constructor of my view model, I call a function (BuildMapLayerCollection) that sets up my layers for me, and here is the function:


protected void BuildMapLayerCollection()
        {
            MapLayerCollection = new LayerCollection();

            //Build the Layer Collection.
            ArcGISTiledMapServiceLayer baseLayer = new ArcGISTiledMapServiceLayer();
            baseLayer.Url = "http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer";
            baseLayer.ID = "baseMap";

            MapLayerCollection.Add(baseLayer);                        
        }



The only thing I can see that I've done differently is that I've set an ID for the layer.  I don't know if this is mandatory, but I've done so anyway.

Hope that proves helpful!

Lisa
0 Kudos
AndrewMurdoch
Regular Contributor
Lisa,
After you confirmed that this should work, I revised my approach.  Now I don't try to create a new LayerCollection but just update an existing layer in the bound LayerCollection (using the ID property I hadn't used before). 

This code works to change the "BaseLayer" layer object and I have it working on a button click in the View Model.

            
            ArcGISDynamicMapServiceLayer tempBaseLayer = new ArcGISDynamicMapServiceLayer();
            tempBaseLayer = (ArcGISDynamicMapServiceLayer)_myLayers["BaseLayer"];
            if (tempBaseLayer.Url == "http://myserver.com/ArcGIS/rest/services/ITM/mapservice1/MapServer")
            {
                tempBaseLayer.Url = "http://myserver.com/ArcGIS/rest/services/ITM/mapservice2/MapServer";
            }
            else
            {
                tempBaseLayer.Url = "http://myserver.com/ArcGIS/rest/services/ITM/mapservice1/MapServer";
            }


Thanks for your help!
Andrew
0 Kudos