Select to view content in your preferred language

Children of Group Layer - visibility and display questions.

2894
3
11-21-2012 09:53 AM
Ravichandran_M_Kaushika
Regular Contributor
dear Readers,

this is the 1st time, i am using group layers and have some questions associated with this. all layers are added at run time based on information present in web.config file.

AGS 10.1 Rest services are consumed in the application
VS 2010, SP*
SL 5.x and ESRI API 3.x.

this sl applicaiton is using editor widget and saves the graphics explicitly as explained in: http://resources.arcgis.com/en/help/silverlight-api/samples/start.htm#EditToolsExplicitSave

I have attached a pdf to indicate the old layer list and old legend to see how it looks.

<basics:TabItem Header="Old LayerList">
      <StackPanel>
       <ListBox x:Name="lstBox4Layers" Background="Transparent" ItemsSource="{Binding ElementName=Map4DataMgmt, Path=Layers}">
        <ListBox.ItemTemplate>
         <DataTemplate>
          <StackPanel Orientation="Horizontal" x:Name="stkPnl4BoundLayersInfo">
           <!-- Background="Transparent" -->
           <CheckBox IsChecked="{Binding Visible, Mode=TwoWay}"/>
           <Slider Margin="-5,0,0,0" Minimum="0" Maximum="1" Width="50" Value="{Binding Opacity, Mode=TwoWay}" ToolTipService.ToolTip="{Binding Opacity, Mode=TwoWay}" Height="20"/>
           <TextBlock Text="{Binding ID, Mode=OneTime}" Margin="5,0,0,0"/>
           <ToolTipService.ToolTip >
            <ToolTip>
             <StackPanel MaxWidth="500">
              <TextBlock FontWeight="Bold"  Text="{Binding CopyrightText, Mode=OneWay}"/>
              <TextBlock FontWeight="Bold" Text="{Binding Title, Mode=OneWay}" />
              <TextBlock Text="{Binding ServiceDescription}" TextWrapping="Wrap" Margin="0,10,0,0"/>
              <TextBlock Text="{Binding Abstract}" TextWrapping="Wrap" Margin="0,10,0,0"/>
             </StackPanel>
            </ToolTip>
           </ToolTipService.ToolTip>
          </StackPanel>
         </DataTemplate>
        </ListBox.ItemTemplate>
       </ListBox>
      </StackPanel>
     </basics:TabItem>
     <basics:TabItem Header="Old Legend">
      <esri:Legend x:Name="XXMyLegend" Map="{Binding ElementName=Map4DataMgmt}"  LayerItemsMode="Tree" />
     </basics:TabItem>



Based on the name of the service, at runtime code decides whether it is ags tiled service or ags dynamic service and adds them to the appropriate group layer. End users wanted them to be grouped, so a starting point: i put them into 2 groups, TiledLayerGroup and DynLayerGroup.

  if (_lstReferenceDisplayURLs[iOrdialInList].Contains("~C"))
                {
                    ArcGISTiledMapServiceLayer atsCachedLayer = new ArcGISTiledMapServiceLayer();
                    atsCachedLayer.Url = strURLOfCurrentLayer.Replace("~C", "");
                    atsCachedLayer.ID = _lstReferenceDisplayNames[iOrdialInList].Trim();

                  //  atsCachedLayer.Visible = bCheckedVisibility;
                    atsCachedLayer.Opacity = dblCurrLayerOpacity;
                    atsCachedLayer.InitializationFailed += new EventHandler<EventArgs>(MapLayer_InitializationFailed);
                  //  Map4DataMgmt.Layers.Add(atsCachedLayer);
                    InsertLayerInAGroupLayer(atsCachedLayer, "TiledLayerGroup");
                }
                else
                {
                    ArcGISDynamicMapServiceLayer adsDynServLayer = new ArcGISDynamicMapServiceLayer();
                    adsDynServLayer.Url = strURLOfCurrentLayer;
                    adsDynServLayer.ID = _lstReferenceDisplayNames[iOrdialInList];
                    adsDynServLayer.Opacity = dblCurrLayerOpacity;
                  //  adsDynServLayer.Visible = bCheckedVisibility;
                    adsDynServLayer.InitializationFailed += new EventHandler<EventArgs>(MapLayer_InitializationFailed);
                    InsertLayerInAGroupLayer(adsDynServLayer, "DynLayerGroup");
                    //Map4DataMgmt.Layers.Add(adsDynServLayer);
                }


 private void InsertLayerInAGroupLayer(Layer lyr2BInsertedIntoGrpLayer, string strGroupLayerID)
        {            
            GroupLayer glGrpLayer = (GroupLayer)Map4DataMgmt.Layers[strGroupLayerID];
            if (glGrpLayer == null)
            {
                glGrpLayer = new GroupLayer();
                glGrpLayer.ID = strGroupLayerID;
                
                Map4DataMgmt.Layers.Add(glGrpLayer);
            }
            glGrpLayer.ChildLayers.Add(lyr2BInsertedIntoGrpLayer);
        }

 


Q1: why is the layer list on 'Old Layer List' tab not showing like this example: http://resources.arcgis.com/en/help/silverlight-api/samples/start.htm#GroupLayers - all children layers are hidden under TiledLayerGroup Checkbox without the ability for me to individually set the transparency or visibiliy. Also, i have to load the layers at run time - not at design time like this example.

Q2: it is NOT ok for the users to have all children layers visible and they would like to uncheck something or change it transparency? any examples to show the children layers of a group layers having visibility flags and transparency slider at the users disposal.

Q3. I am always forced to set visibiltiy of children layers to be true and it messes up the display and the performance of the application - any ideas to work around the same?


thanks for taking the time to read this long posting.

regards
ravi.
0 Kudos
3 Replies
DominiqueBroux
Esri Frequent Contributor
Your ListBox is binded to the Layers property of the map.
It means that you get only the first level of group layers. To get others layers you need to get through the layers hierarchy.

The easier way to do that is to use the LegendControl. The GroupLayer sample seems to do exactly what you are expecting, no?
0 Kudos
JohanCarlsson
Regular Contributor
Hi!

I'd like to achieve the same behavior of the legend as displayed in the sample provided by Dominique, i.e. displaying all levels of sub layers. I've followed the code in the example and I've bound my legend control to the map. However, I still only get the first level of the layer.

Here's the code for my legend control:

        void Layers_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            MapLegend_Loaded(null, null);
        }

        private void MapLegend_Loaded(object sender, RoutedEventArgs e)
        {
            this.MapLegend.Map = map;
            IDictionary<string, string> layersStr = new Dictionary<string, string>();
            foreach (Layer layer in map.Layers.Reverse())
            {
                string layerName = MapApplication.GetLayerName(layer);
                if (!(layer is GraphicsLayer) && !(layer is SKSGraphicsLayer) && layerName != null)
                    layersStr.Add(layer.ID, layerName);
                if(layer is FeatureLayer)
                    layersStr.Add(layer.ID, layerName);
            }

            this.MapLegend.LayerIDs = layersStr.Keys.ToArray();
            this.MapLegend.ShowOnlyVisibleLayers = true;
            this.MapLegend.LayerItemsMode = ESRI.ArcGIS.Client.Toolkit.Legend.Mode.Tree;
            
            string[] layerNameArray = layersStr.Values.ToArray();
            int i = 0;
            
            foreach (var item in this.MapLegend.LayerItems)
            {
                item.IsExpanded = false;
                item.Label = TrimLayerName(layerNameArray);
                i++;
            }
        }

        private string TrimLayerName(string layerNameString)
        {
            string[] layerNameArr = layerNameString.Split('[');
            return layerNameArr[0].Trim();
        }

        private void MapLegend_Refreshed(object sender, ESRI.ArcGIS.Client.Toolkit.Legend.RefreshedEventArgs e)
        {
            if (e.LayerItem.LayerItems != null)
                foreach (LayerItemViewModel layerItemVM in e.LayerItem.LayerItems)
                    if (layerItemVM.IsExpanded)
                        layerItemVM.IsExpanded = false;
        }


The picture shows the behavior of the legend right now, but I'd like to display every level. What am I doing wrong?
0 Kudos
DominiqueBroux
Esri Frequent Contributor
I'd like to achieve the same behavior of the legend as displayed in the sample provided by Dominique, i.e. displaying all levels of sub layers. I've followed the code in the example and I've bound my legend control to the map. However, I still only get the first level of the layer.


The issue is likely in your XAML code but you donn't provide it.

From your screenshot, my best bet is either that you set the LegendItemTemplate to null or that you define your own legend Template.
0 Kudos