Select to view content in your preferred language

How to control order of layers using codebehind

983
7
07-23-2010 08:58 AM
PLadd
by
Frequent Contributor
I'm adding the layers to MyMap using code behind. 

The order in which I've written the code is not the order in which they appear on the map.  How do I control that?  Is it a timing thing (as in don't load the next one until the first one is done loading)? 

In other words, in the code below I add Aerials, Buildings, and Parcels in that order.  I expect it to appear from bottom to top in that order but what I'm getting is Parcels, Aerials, Buildings from bottom to top.  I expected them to appear in the order I've written them in code.

Here's a sample of how I'm doing the codebehind:

//Parcels
            ArcGISTiledMapServiceLayer layerParcels = new ArcGISTiledMapServiceLayer()
            {
                Url = "http://myserver/arcgis/rest/services/Parcels3/MapServer",
                ID = "Parcels",
                Visible = true
            };

//Buildings
            ArcGISTiledMapServiceLayer layerBuildings = new ArcGISTiledMapServiceLayer()
            {
                Url = "http://myserver/arcgis/rest/services/Buildings/MapServer",
                ID = "Buildings",
                Visible = true
            };

//Aerials2005
            ArcGISTiledMapServiceLayer layerAerials2005 = new ArcGISTiledMapServiceLayer()
            {
                Url = "http://myserver/arcgis/rest/services/Aerials2005/MapServer",
                ID = "Aerials2005",
                Visible = false
            };

layerAerials2005.InitializationFailed += layer_InitializationFailed;
AddLayerWithCredentials(layerAerials2005);
layerBuildings.InitializationFailed += layer_InitializationFailed;
AddLayerWithCredentials(layerBuildings);
layerParcels.InitializationFailed += layer_InitializationFailed;
AddLayerWithCredentials(layerParcels);

void layer_InitializationFailed(object sender, EventArgs e)
        {
           
        }

        private void AddLayerWithCredentials(ArcGISTiledMapServiceLayer layer)
        {
            WebClient challengeRequest = new WebClient();
            challengeRequest.DownloadStringCompleted += (sender, args) =>
            {
                MyMap.Layers.Add(layer);
                TOC.Refresh();
            };

            challengeRequest.DownloadStringAsync(new Uri(layer.Url));  
        }
0 Kudos
7 Replies
JenniferNery
Esri Regular Contributor
Since you are adding the layers to the map based on an asynchronous event (DownloadStringCompleted), you cannot expect the order of the layers to be always the same.

If you really have to modify the order of the layers in your map, once all layers have been added to your map you can modify the existing layer collection by doing the following:
            Layer Aerials2005 = this.MyMap.Layers["Aerials2005"];
            Layer Buildings = this.MyMap.Layers["Buildings"];
            Layer Parcels = this.MyMap.Layers["Parcels"];
            LayerCollection lc = this.MyMap.Layers;
            lc.Clear();
            if (Aerials2005 != null)
                lc.Add(Aerials2005);
            if (Buildings != null)
                lc.Add(Buildings);
            if (Parcels != null)
                lc.Add(Parcels);


Jennifer
0 Kudos
PLadd
by
Frequent Contributor
Thanks Jennifer,

I put your code in MyMap_Loaded and when I stepped through it, each layer come back null at this point:

if (Aerials2002 != null)
   lc.Add(Aerials2002);

So the order isn't changing.  Any thoughts?  Am I putting your code in the wrong place?  See below:

        private void MyMap_Loaded(object sender, RoutedEventArgs e)
        {
                Layer Hillshade = this.MyMap.Layers["Hillshade"];
                Layer Aerials2002 = this.MyMap.Layers["Aerials2002"];
                Layer Aerials2005 = this.MyMap.Layers["Aerials2005"];
                Layer BaseMap = this.MyMap.Layers["BaseMap"];
                Layer Buildings = this.MyMap.Layers["Buildings"];
                Layer Parcels = this.MyMap.Layers["Parcels"];
                LayerCollection lc = this.MyMap.Layers;
                lc.Clear();
                if (Hillshade != null)
                    lc.Add(Hillshade);
                if (Aerials2002 != null)
                    lc.Add(Aerials2002);
                if (Aerials2005 != null)
                    lc.Add(Aerials2005);
                if (BaseMap != null)
                    lc.Add(BaseMap);
                if (Buildings != null)
                    lc.Add(Buildings);
                if (Parcels != null)
                    lc.Add(Parcels);
        }
0 Kudos
JenniferNery
Esri Regular Contributor
You need to call this after all layers have been added, that's the tricky part since you add the layers asynchronously and there's no guarantee that all layers will be added if credentials should fail, right?

To test that you can change the order of the map layers in code, you can add them in a button click event. Once you know all layers were added, click the button and see that the order of layers have been modified.

Jennifer
0 Kudos
DominiqueBroux
Esri Frequent Contributor
As Jennifer mentionned, due to the asynchrone behavior, it might be tricky to know when to reorder the layers.

Perhaps you might reverse the process:
   - declare the layers symchronously (in XAML or in code) in order to control the order
   - remove the layers when credentials fail

Just 2cts (not sure it's ok in your context)
0 Kudos
RobertBurke
Esri Contributor
Hi Patrick,

In the end what kind of behavior are you attempting to create?
Rob Burke
0 Kudos
PLadd
by
Frequent Contributor
Good question, Rob.  Why am I doing all this in the first place, since adding through XAML is so easy and doesn't cause other issues?

Currently our site is only Intranet, so nobody is using it after hours.  Each morning when I come in, the first person to hit the site gets the following:

An unknown error was encountered
Error details
at ESRI.ArcGIS.Client.Layer.OnInitializationFailed(EventArgs e)
at ESRI.ArcGIS.Client.Layer.Initialize()
at ESRI.ArcGIS.Client.ArcGISTiledMapServiceLayer.MapServiceInfoInitFailed(Object sender, RestFaultEventArgs args)

It's as if the layers are in sleep mode.  When I hit the site a second time, the error message goes away (for me and any other subsequent user)

So in searching for a solution, I came across this:

http://forums.esri.com/thread.asp?t=295475&f=2455&c=158

I'm using the 2.0 api but I thought I'd give adding layers in codebehind a shot. 

I presently have this code inserted and I'll wait until tomorrow morning to see what it yields:

void layer_InitializationFailed(object sender, EventArgs e)
        {
            Layer layer = sender as Layer;
            MessageBox.Show(string.Format("Layer '{0}' is currently unavailable. Error: {1}", layer.ID,       layer.InitializationFailure.Message));
        }

If you think it's something else, please advise.

Thanks.
0 Kudos
RobertBurke
Esri Contributor
Hi Patrick

When the error happens have you used Fiddler or similar product to view the http communication to see if there is more to the error?  Have you looked in the Server's Log files to see if anything is written there too?  Did your test work?
Rob Burke
0 Kudos