AnsweredAssumed Answered

Table of Contents for ArcGIS Runtime SDK for .NET v10.2.7

Question asked by AndrewFoster on Nov 1, 2016

We would like confirmation on our approach to building a Table of Contents in WPF using the ArcGIS Runtime SDK for .NET v10.2.7.  We have looked at the Legend control in the Toolkit but it does not seem to provide a way to manage the visibility of each sub-layer.

 

We have the following custom class which represents a map layer/sub-layer node displayed in a WPF TreeView control. We store the Layer Id in the Tag property.

public class TOCNodeClass : INotifyPropertyChanged

    {

        public string DisplayName { get; set; }

        public string Tag { get; set; }

        private bool isChecked;

        public bool IsChecked

        {

            get { return this.isChecked; }

            set

            {

                if (value != this.isChecked)

                {

                    this.isChecked = value;

                    NotifyPropertyChanged();

                }

            }

        }

        private bool isEnabled;

        public bool IsEnabled

        {

            get { return this.isEnabled; }

            set

            {

                if (value != this.isEnabled)

                {

                    this.isEnabled = value;

                    NotifyPropertyChanged();

                }

            }

        }

        public double MinScale { get; set; }

        public double MaxScale { get; set; }

        public ObservableCollection<TOCNodeClass> Nodes { get; set; }

 

        //PropertyChanged Handler

        public event PropertyChangedEventHandler PropertyChanged;

 

        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

    }

 

We have an observable collection public ObservableCollection<TOCNodeClass> TOC { get; set; } to which we add a TOCNodeClass object for each map layer that is added to the MapView.Map.Layers collection.  Note each TOCNodeClass object has its own observable collection to allow adding sub-layers (feature layers).  We are building these objects using the properties found in each map layer’s AllLayersServiceInfo object and subsequently each sub-layer’s FeatureServiceLayerInfo object.

 

We have a WPF TreeView control bound to the TOC observable collection as shown below:

 

<TreeView x:Name="TableOfContents" Width="auto" HorizontalAlignment="Stretch" ItemsSource="{Binding TOC}">

<TreeView.ItemTemplate>

<HierarchicalDataTemplate DataType="{x:Type local:TOCNodeClass}"   ItemsSource="{Binding Nodes}">

<CheckBox x:Name="CheckBoxTOC" Tag="{Binding Tag}" IsEnabled="{Binding IsEnabled}" IsChecked="{Binding IsChecked}" Focusable="false" Checked="CheckBoxTOC_Checked" Unchecked="CheckBoxTOC_Unchecked">

<TextBlock Text="{Binding DisplayName}" FontWeight="Bold" MaxWidth="250" TextTrimming="CharacterEllipsis" />

</CheckBox>

</HierarchicalDataTemplate>

</TreeView.ItemTemplate>

 </TreeView>

 

Here's a list of methods we use to manage the state of the TreeView control:

public async void AddMapLayerToTOC(string strMapLayerId)

private bool AreAllMapLayerParentNodesChecked(TOCNodeClass objMapLayerNode, TOCNodeClass objChildNode)

private bool AreAllTOCParentNodesChecked(ObservableCollection<TOCNodeClass> objCollection, TOCNodeClass objChildNode)

private void CheckBoxTOC_Checked(object sender, RoutedEventArgs e)

private void CheckBoxTOC_Unchecked(object sender, RoutedEventArgs e)

private TOCNodeClass FindTOCNode(ObservableCollection<TOCNodeClass> objNodeCollection, string strTag)

private bool IsLayerEnabled(double dblMinScale, double dblMaxScale)

private void RefreshTOC()

public void RemoveMapLayerFromTOC(string strMapLayerId)

private void ToggleTOC(string strClickedLayerTag, bool blnIsChecked)

private void MapView_Main_NavigationCompleted(object sender, EventArgs e)

 

We found that we must manage each map layer’s ArcGISDynamicMapServiceLayer.VisibleLayers collection to show and hide the individual sub-layers (feature layers) by adding and removing the sub-layer’s Layer Id.  To complicate matters, each time a sub-layer’s checkbox changes state, we must inspect the checkbox state of all its parent nodes and all its sub-layer nodes to determine the visibility of each sub-layer.

 

We also have code in the MapView’s NavigationCompleted event to refresh the Table of Contents, as well as each map layer’s VisibleLayers collection, based on each sub-layer’s Min. Scale and Max. Scale settings.

 

Although we’ve made this work, it would be good to know if there's a better way to build a Table of Contents control.  Ultimately, we would like to display each sub-layer’s symbology in the Table of Contents; still trying to figure this out.

 

Thank you in advance for your suggestions.

Outcomes