The Legend is a utility control that displays the symbology of Layers and their description for map interpretation. By altering its various DataTemplates, the Legend Control functionality can be altered to behave like an interactive Table of Contents (TOC).

The Legend Control is a User Interface (UI) control which provides useful narrative and graphic descriptions for understanding what is being viewed in the Map. It displays the Layer.ID name, sub-layer name(s) (via the LayerInfo.Name Property), and any associated graphical symbols with their Label(s) (using the LayerItemViewModel.LegendItems Collection). Additionally, ToolTip information can obtained revealing detailed Layer information (such as: Layer.ID, LayerItemViewModel.SubLayerID, LegendItemViewModel.Label, LegendItemViewModel.Description, LayerItemViewModel.MinimumResolution, LayerItemViewModel.MaximumResolution, etc.) when the user hovers the cursor over a Layer/sub-Layer name in the Legend. In its default mode of operation, end-users interact with the Legend Control to expand and collapse the nodes to view as much information as desired about a particular Layer.

In most use cases, developers typically only need to set a few core Properties in order to have a Legend that displays useful information about the Layers in the Map. The core properties are:

Legend.Map - This Property binds the Legend to the Map Control. It is required that this Property be set or else there will be no communication between the Map and the Legend. Legend.LayerItemsMode - This Property controls whether the Legend displays information in an expanded Tree hierarchy for all Legend items or in a Flat structure which shows only the lowest Layer item leaves (The Layer.ID, LayerItemViewModel.SubLayerID, and group-layer labels hierarchy information will not be displayed). The Legend.Mode Enumeration is used to define the Tree or Flat options. The default Enumeration value for the Legend.LayerItemsMode is Flat. Legend.ShowOnlyVisibleLayers - This Property controls the display of items in the Legend if they are visible in the Map. It accepts a Boolean. The default is True, meaning that only visible layers in the Map will display in the Legend. A Layer may have scale dependency rendering (i.e. the Layer.MinimumResolution and/or Layer.MaximumResolution) values which set which limits when a Layer can be viewed in the Map at a particular zoom level. A Legend.ShowOnlyVisibleLayers value of False means that even if the Layer is not currently displaying in the Map it will still be listed in the Legend. Legend.LayerIDs - This Property defines which Layers are participating in the Legend Control. By default this value is set to null/Nothing; which means that all Layers in the Map Control participate in the Legend Control. Developers can limit which Layers are listed in the Legend Control (even though they are still viewable in the Map Control) by specifying a comma-delimmited string using Layer.ID values. Note: Do not use Layer.ID values that contain embedded commas as this will cause problems tokenizing in the Legend.LayerIDs Property.

The Legend Control is highly customizable such that developers can override the default behavior of the various DataTemplates to alter the behavior of the control to make it behave like a TOC. A TOC provides the same useful narrative and graphical information as a Legend but adds the extra functionality of allowing users to turn on/off the visibility of individual Layers (and their sub-Layers where applicable). Depending on the developers creativity even other specialized functions can be programmed into the DataTemplates to perform functions like: controlling the opacity of individual Layers (and their sub-Layers where applicable), setting thresholds at which scale a particular Layer is visible, allowing for a specific Layer to be selected and highlighted in the Map, and more. Additional details on what parts of the Legend Control can be customized by the various DataTemplate Properties will be discussed later in this document.

The Legend Control can be created at design time in XAML or dynamically at runtime in the code-behind. The Legend Control is one of several controls available in the Toolbox in Visual Studio when the ArcGIS API for Silverlight is installed, The Legend Control is one of several controls available in the Toolbox in Visual Studio when the ArcGIS Runtime SDK for WPF is installed, There are no controls that can be dragged into the XAML design surface from the Toolbox as part of the ArcGIS Runtime SDK for Windows Phone installation. Developers need to type the correct syntax in the XAML to have the controls appear in the visual designer, see the following screen shot:

Example of the Legend Control on the XAML design surface of a Silverlight application.

Example of the Legend Control on the XAML design surface of a WPF application.

Example of the Legend Control on the XAML design surface of a Windows Phone application.

The default appearance of the Legend Control can be modified using numerous inherited Properties from System.Windows.FrameworkElement, System.Windows.UIElement, and System.Windows.Controls. An example of some of these Properties include: .Height, .Width, .BackGround, .BorderBrush, .BorderThickness, .Foreground, .HorizontalAlignment, .VerticalAlignment, .Margin, .Opacity, .Visibility, etc.

Note: You cannot change the core behavior of the sub-components (i.e. Image, ToolTipService, StackPanel, TextBlock, DataTemplate, Grid, ContentControl, ContentPresenter, ESRI.ArcGIS.Client.Toolkit.Primitives.TreeViewExtended, etc.) of the Legend Control using standard Properties or Methods alone. To change the core behavior of the sub-components and their appearance of the Control, developers can modify the Control Template in XAML and the associated code-behind file. The easiest way to modify the UI sub-components is using Microsoft Expression Blend. Then developers can delete/modify existing or add new sub-components in Visual Studio to create a truly customized experience. A general approach to customizing a Control Template is discussed in the ESRI blog entitled: Use control templates to customize the look and feel of ArcGIS controls. A specific code example of modifying the Control Template of the Legend Control to can be found in the Legend.Map Property document.

Rather than edit the full Control Template of the Legend Control, ESRI has exposed three DataTemplates Properties where developers can target the UI customization to a more limited scope. Each DataTemplate and a description of what part of the Legend Control it has bearing over is listed here:

Legend.MapLayerTemplate

This DataTemplate controls what is viewed in the Legend for the highest level of information about a particular Layer. It presents each Layer name (via the LegendItemViewModel.Label Property) shown in the Map in a ContentControl with a node to expand any sub-Layer information. When a user hovers the cursor over the Legend.MapLayerTemplate section, a ToolTip appears displaying the additional information about the Layer including: Layer.Copyright, LegendItemViewModel.Description, LayerItemViewModel.MinimumResolution, and LayerItemViewModel.MaximumResolution. The MapLayerTemplate value is optional; by default the Legend.LayerTemplate is used.

Note: The Legend.LayerItemsMode Property has great impact on what is displayed in the Legend. For users who want to see the most information available in the Legend, developers should set the LayerItemsMode to Tree. If customizations are made to the MapLayerTemplate and they seem to be overridden at runtime back to a default setting, it is most likely that the LayerItemsMode is set to the default of Flat and it should be set to Tree.

The objects that have Binding occur in the MapLayerTemplate are implied to be the Properties of the LayerItemViewModel Class.

At the MapLayerTemplate level, one common customization technique would be add a TOC style of interaction. Developers could add a CheckBox to manage the visibility of a Layer (including its sub-Layers) or add a Slider to control the Opacity of the Layer (including its sub-Layers). Code examples of modifying the MapLayerTemplate can be found in the Legend.MapLayerTemplate and Legend.LayerTemplate documents.

Legend.LayerTemplate

This DataTemplate controls what is viewed in the Legend for the middle level of information about a particular Layer. It presents each sub-Layer name (via the LegendItemViewModel.Label Property) in a ContentControl with a node to expand any LegendItem information or any other nested sub-Layer (aka. group layer) information. When a user hovers the cursor over the Legend.LayerTemplate section, a ToolTip appears displaying the additional information about the sub-layer including: Layer.ID, LegendItemViewModel.Label, LegendItemViewModel.Description, LayerItemViewModel.SubLayerID, LayerItemViewModel.MinimumResolution, and LayerItemViewModel.MaximumResolution. This template is used by default for all Layers except the LegendItems as the lowest level.

The objects that have Binding occur in the LayerTemplate are implied to be the Properties of the LayerItemViewModel Class.

At the Legend.LayerTemplate level, one common customization technique would be to add TOC style of interaction. Developers could add a CheckBox to manage the visibility of sub-Layer elements. You could add a Slider similar to the Legend.MapLayerTemplate and you will get Sliders appearing for each sub-Layer but the behavior may not be as you would expect. Adjusting a Slider on one sub-Layer would also control the Opacity of the other sub-Layers simultaneously. Note: FeatureLayers do not have the ability to control the visibility or opacity of sub-Layer elements. A code examples of modifying the Legend.LayerTemplate can be found in the Legend.LayerTemplate document.

Legend.LegendItemTemplate

This DataTemplate controls what is viewed in the Legend for the lowest level of information about a particular Layer. It presents each LegendItem via its image (LegendItemViewModel.ImageSource) and label description (LegendItemViewModel.Label). No ToolTip information is provided for an individual LegendItem by default.

The objects that have Binding occur in the LegendItemTemplate are implied to be the Properties of the LegendItemViewModel Class.

At the Legend.LegendItemTemplate level, the customization options become more limited due to the map service information being passed back from the ArcGIS Server REST end point. The LegendItemViewModel class contains the most atomic level of information about a particular LegendItem. Turning on/off individual LegendItems or changing their opacity is not possible on any Layer type. It is possible to get creative and perform TOC style user interactions at the Legend.LegendItemtemplate level by discovering the parent objects of individual LegendItems; see the code example in the Legend.LegendItemTemplate for one such customization.

It should be noted that it is possible to customize one or more of the Legend Control DataTemplates at the same time. There are established default values for each DataTemplate, so setting one will not necessarily override the others that have been set by default. Significant testing should be done on all of the Layers in the customized application to ensure that the desired behavior has been achieved. Some Layers have different behavior in rendering items in the Legend and should be tested thoroughly.

The following screen shot demonstrates which part of the Legend Control corresponds to the three DataTemplates. The Layer (ID = "United States") that is being displayed is an ArcGISDynamicMapServiceLayer with three sub-Layers (ushigh, states, and counties). The information found in the ArcGIS Services Directory about the ArcGISDynamicMapServiceLayer corresponds to what is shown in the Map and Legend Controls.

Using the ArcGIS Services Directory to view information about an ArcGISDynamicMapServiceLayer and how that corresponds to what is displayed in the Map and Legend Control. The DataTemplate parts of the Legend Control are specified.

TIP: It is typically necessary for developers to specify the Layer.ID name for Layers in the Map Control. This can be done in XAML or code-behind. If a Layer.ID value is not specified, then a default Layer.ID value is provided based upon the URL of the ArcGIS Server map service.

Наследование: System.Windows.Controls.Control
        private void Legend_Refreshed(object sender, Legend.RefreshedEventArgs e)
        {
            LayerItemViewModel removeLayerItemVM = null;

            // If a map layer has sublayers, iterate through them.
            if (e.LayerItem.LayerItems != null)
            {
                // Iterate through all the sublayer items.
                foreach (LayerItemViewModel layerItemVM in e.LayerItem.LayerItems)
                {
                    // Collapse all sublayers in the legend.
                    if (layerItemVM.IsExpanded)
                        layerItemVM.IsExpanded = false;

                    // Remove the sublayer named "states" from the legend.  The layer remains visible in the map.
                    if (layerItemVM.Label == "states")
                        removeLayerItemVM = layerItemVM;
                }

                if (removeLayerItemVM != null)
                    e.LayerItem.LayerItems.Remove(removeLayerItemVM);
            }
            else
            {
                // Collapse all map layers in the legend.
                e.LayerItem.IsExpanded = false;
            }
        }
 private void Legend_Refreshed(object sender, Legend.RefreshedEventArgs e)
 {
   if (e.LayerItem.LayerItems != null)
     foreach (LayerItemViewModel layerItemVM in e.LayerItem.LayerItems)
       if (layerItemVM.IsExpanded)
         layerItemVM.IsExpanded = false;
 }
Пример #3
0
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            ConfigureButton = GetTemplateChild(PART_CONFIGUREBUTTON) as Button;
            if (ConfigureButton != null)
                ConfigureButton.Click += ConfigureButton_Click;

            _legend = GetTemplateChild(PART_LEGEND) as Legend;
 
            if (Map == null && MapApplication.Current != null)
                Map = MapApplication.Current.Map;
        }
Пример #4
0
        /// <summary>
        /// Refresh legend
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Legend_Refreshed(object sender, Legend.RefreshedEventArgs e)
        {
            try
            {
                if (e.LayerItem.Layer.GetType() == typeof(FeatureLayer))
                {
                    e.LayerItem.IsExpanded = false;
                }
                else
                    if (e.LayerItem.Layer.GetType() == typeof(GraphicsLayer))
                    {
                        this.tocView.LayerLegend.LayerItems.Remove(e.LayerItem);
                    }
                    else
                    {
                        ArcGISMapLayer layer = null;
                        foreach (var item in configuration.GetApplicationConfig().MapConfig.BaseMapLayers)
                        {
                            layer = item.Layers.FirstOrDefault(b => b.Title.Equals(e.LayerItem.Layer.ID));
                            if (layer != null)
                                break;
                        }

                        if (layer != null && !layer.Expandable)
                        {
                            // Remove the details for the base layers if no details are required
                            if (e.LayerItem.LayerItems != null && e.LayerItem.LayerItems.Count > 0)
                            {
                                e.LayerItem.LayerItems.Clear();
                            }
                        }
                        else
                        {
                            if (e.LayerItem.LayerItems != null && e.LayerItem.LayerItems.Count > 0)
                            {
                                for (int i = 0; i < e.LayerItem.LayerItems.Count; i++)
                                {
                                    e.LayerItem.LayerItems[i].IsExpanded = false;
                                }
                            }
                        }
                    }

            }
            catch (Exception ex)
            {
                ShowErrorMessagebox.Raise(new Notification
                {
                    Content = String.Format("Legend_Refreshed-{0}[{1}]", ex.Message, ex.StackTrace),
                    Title = "System error"
                });
            }
        }
 private void Legend_Refreshed(object sender, Legend.RefreshedEventArgs e)
 {
     // Clear the sub items from the basemap layer.
     if (e.LayerItem.Layer == _worldTopographicBasemap)
     e.LayerItem.LayerItems.Clear();
 }