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

1119
3
11-01-2016 11:25 AM
Highlighted
New Contributor II

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.

Tags (1)
Reply
0 Kudos
3 Replies
Highlighted
MVP Esteemed Contributor

Andrew,

   I see you never got any replies to this. I am looking for a TOC in dot net SDK and am wondering how this worked out for you now that it is March 2019? Did you continue to build on this and add symbology?

Reply
0 Kudos
Highlighted
New Contributor II

Yes, we built the table of contents as described in the original post and later added Symbology for each feature layer.  We had to access each feature layer's FeatureServiceLayerInfo.DrawingInfo properties to determine the type of Symbology renderer used.  A feature class with one symbol uses a SimpleRender; one with multiple symbols uses either a UniqueValueRenderer or a ClassBreaksRenderer.  We added a node in the table of contents under the respective feature layer node for each symbol.  This required a new property in our TOCNodeClass to hold the symbol's image which is of type System.Windows.Media.ImageSource.  We retrieved the image by calling the feature layer render's Symbol.CreateSwatchAsync() method.

Surprisingly, the table of contents displays really fast even with multiple map layers in the map view.  Post your email address and I'll try to send you a code sample.

Reply
0 Kudos
Highlighted
MVP Esteemed Contributor

Andrew,

   Can you follow me on GeoNet so that I can private message you? I would rather not post my email on GeoNet. Thanks for offering to share your work. That is waht makes GeoNet a great community.

Reply
0 Kudos