Select to view content in your preferred language

DBROUX's legend reoganize sample

1133
9
04-02-2014 09:46 AM
LanceCrumbliss
Frequent Contributor
Dbroux, I've used your sample code here http://broux.dominique.free.fr/Silverlight/InteractiveSDK/Default.htm#LegendReorganize in the past.  It works fine.  What I'd like to do now is move a FeatureLayer that is the top layer in the map (for mildly complex layer order visibility reasons) into a Group in the Legend.  I can do that, but of course the Visibility of the GroupLayer is not respected by the "moved" FeatureLayer. How can I make the FeatureLayer respect the Visibility property of the GroupLayer it is "moved" to in the Legend?

Attached shows the GroupLayer after reorganization.  I've not attached the map, but as a result of the Visibility of the GroupLayer, the bottom three layers do not render (correct behavior), however the top one - "Sea Birds" does (correct, but not desired).

Lance
0 Kudos
9 Replies
DominiqueBroux
Esri Frequent Contributor
I answered to a similar question in this thread.
Hope this helps.
0 Kudos
LanceCrumbliss
Frequent Contributor
I answered to a similar question in this thread.
Hope this helps.


Thanks Dbroux.  However, there seem to be differences between the GroupLayer type and types that impliment ISubLayerVisibilitySupport (Like ArcGISDynamicMapServiceLayer).  I can't seem to find the right combination of handlers that mimic the functionality of an unmodified GroupLayer (all childlayers of the group respecting the visibility of the parent grouplayer).
0 Kudos
DominiqueBroux
Esri Frequent Contributor
Thanks Dbroux.  However, there seem to be differences between the GroupLayer type and types that impliment ISubLayerVisibilitySupport (Like ArcGISDynamicMapServiceLayer).  I can't seem to find the right combination of handlers that mimic the functionality of an unmodified GroupLayer (all childlayers of the group respecting the visibility of the parent grouplayer).


At first glance, I would say that you have only to subscribe to GroupLayer.PropertyChanged event and no more worry about ISubLayerVisibilitySupport.

i.e something like:

   _groupLayerItem .Layer.PropertyChanged += (s, evt) =>
    {
        if (evt.PropertyName == "Visible")
            UpdateFeatureLayerVisibility();
    };
0 Kudos
LanceCrumbliss
Frequent Contributor
That would seem to tie the visibility of the Featurelayer directly to the visibility of GroupLayer.  In other words, toggling the GroupLayer on would turn on the FeatureLayer,even if the FeatureLayer is set to no visible.  Further, if the FeatureLayer is toggled, it doesn't respect the GroupLayer visibility.

 Private Sub UpdateFeatureLayerVisibility(sender As Layer)        
If _seaBirdsLivm IsNot Nothing AndAlso _environtmentalGroupLayerLivm IsNot Nothing Then
            _seaBirdsLivm.IsEnabled = _environtmentalGroupLayerLivm.Layer.Visible AndAlso _environtmentalGroupLayerLivm.IsEnabled
        End If
    End Sub




    Private _seaBirdsHasBeenReordered As Boolean
    Private _environtmentalGroupLayerLivm As LayerItemViewModel
    Private _seaBirdsLivm As LayerItemViewModel
    Private Sub esriLegend_Refreshed(sender As Object, e As Toolkit.Legend.RefreshedEventArgs)
        If e.LayerItem.Label = "Sea Birds" Then
            _seaBirdsLivm = e.LayerItem
            e.LayerItem.LayerItems = Nothing
        End If
        If Not _seaBirdsHasBeenReordered Then
            _environtmentalGroupLayerLivm = esriLegend.LayerItems.FirstOrDefault(Function(l) l.Label = "Environmental Layers")
            If _environtmentalGroupLayerLivm IsNot Nothing AndAlso _environtmentalGroupLayerLivm.LayerItems IsNot Nothing AndAlso _seaBirdsLivm IsNot Nothing Then


                AddHandler _environtmentalGroupLayerLivm.Layer.PropertyChanged,
                    Sub(s As Object, evt As PropertyChangedEventArgs)
                        If evt.PropertyName = "Visible" Then
                            UpdateFeatureLayerVisibility(CType(s, Layer))
                        End If
                    End Sub
                _environtmentalGroupLayerLivm.LayerItems.Insert(0, _seaBirdsLivm)
                esriLegend.LayerItems.Remove(_seaBirdsLivm)
                _seaBirdsHasBeenReordered = True
            End If
        Else
            If _seaBirdsLivm IsNot Nothing Then esriLegend.LayerItems.Remove(_seaBirdsLivm)
        End If
    End Sub
0 Kudos
LanceCrumbliss
Frequent Contributor
Hm, maybe not possible/practical?
0 Kudos
DominiqueBroux
Esri Frequent Contributor
Hm, maybe not possible/practical?


You should get something working 'à la google' with code like:

private LayerItemViewModel _featureLayerItem;
private LayerItemViewModel _groupLayerItem;
private void Legend_Refreshed(object sender, Legend.RefreshedEventArgs e)
{
    var legend = sender as Legend;
    if (legend == null)
        return;

    // initialize group layer item once
    if (_groupLayerItem == null)
    {
        _groupLayerItem = legend.LayerItems.FirstOrDefault(l => l.Layer is GroupLayer); // here we suppose there is only one group layer but might be based on ID as well
        if (_groupLayerItem != null)
            _groupLayerItem.PropertyChanged += GroupLayerItem_PropertyChanged;
    }

    if (e.LayerItem.Layer is FeatureLayer && _groupLayerItem != null && !_groupLayerItem.LayerItems.Contains(e.LayerItem))
    {
        _featureLayerItem = e.LayerItem; // store feature layer item
        _featureLayerItem.PropertyChanged += FeatureLayerItem_PropertyChanged;
        legend.LayerItems.Remove(_featureLayerItem); // remove feature layer from the legend root (else it would be duplicated)
        // Add feature layer item in the group layer
        _groupLayerItem.LayerItems.Add(_featureLayerItem);
    }
}

void GroupLayerItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    // synchronize feature layer visibility on group layer
    if (e.PropertyName == "IsVisible")
        _featureLayerItem.Layer.Visible = _groupLayerItem.IsVisible;
}
void FeatureLayerItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    // if feature layer item is toggled on, toggle on the group layer as well
    if (e.PropertyName == "IsEnabled" && _groupLayerItem != null && ((LayerItemViewModel)sender).IsEnabled)
            _groupLayerItem.IsEnabled = true;
}


That being said, I don't see why you don't set  the layers in your map as you want to see them in the legend. But I may miss something.
0 Kudos
LanceCrumbliss
Frequent Contributor
Thanks dbroux,  I'll see how that works. 

That being said, I don't see why you don't set the layers in your map as you want to see them in the legend. But I may miss something.


Maybe i'm missing something here:  the issue is if I set them in the map as I want to see them in the legend, then points will be obscured by polygons.
0 Kudos
LanceCrumbliss
Frequent Contributor
Darn.  This doesn't do it either 🙂  The two main drawbacks are:

- Toggling on the GroupLayer turns on the transfered in FeatureLayer, even if the latter is off.
- Toggling on the transfered in FeatureLayer turns on the GroupLayer, which is different behavior than the non transfered in FeatureLayers in the GroupLayer.
0 Kudos
DominiqueBroux
Esri Frequent Contributor

- Toggling on the GroupLayer turns on the transfered in FeatureLayer, even if the latter is off.


It's why I said 'a la google'. Turning on/off the group layer, turns the sublayers as well.
You can change this behavior in GroupLayerItem_PropertyChanged. However, for consistency, we have still to turn off the feature layer when you turn off the group layer (else the FL would be visible while, in the legend, it appears inside a non visible group layer).
Something like:
void GroupLayerItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    // synchronize feature layer visibility on group layer
    if (e.PropertyName == "IsVisible" && !_groupLayerItem.IsVisible)
        _featureLayerItem.Layer.Visible = _groupLayerItem.IsVisible;
}




- Toggling on the transfered in FeatureLayer turns on the GroupLayer, which is different behavior than the non transfered in FeatureLayers in the GroupLayer.

You could change this behavior in FeatureLayerItem_PropertyChanged (actually by removing all the code) but you would run into the same visual inconsistency as in previous case: FL visible that seems to be inside a non visible group layer.
0 Kudos