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.