I'd like to organize items (layer items) in the legend control into headings, for example SL headered items or accordion items.
<Style x:Key="Accordion" TargetType="esri:Legend"> <Setter Property="LayerItemsMode" Value="Flat" /> <Setter Property="Foreground" Value="Black" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="esri:Legend"> <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" > <toolkit:Accordion Background="{TemplateBinding Background}" Foreground="Black" ItemsSource="{TemplateBinding LayerItems}" HorizontalAlignment="Stretch" SelectionMode="ZeroOrMore"> <toolkit:Accordion.ItemTemplate> <DataTemplate > <!-- Map Layer legend item (1st level in legend hierarchy)--> <ContentPresenter Content="{Binding}" ContentTemplate="{Binding Template}" /> </DataTemplate> </toolkit:Accordion.ItemTemplate> <toolkit:Accordion.ContentTemplate> <DataTemplate> <ItemsControl ItemsSource="{Binding LayerItemsSource}" > <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel> <!-- Layer Item or Legend Item (2nd level in legend hierarchy)--> <ContentPresenter Content="{Binding}" ContentTemplate="{Binding Template}" /> <ItemsControl ItemsSource="{Binding LegendItems}"> <ItemsControl.ItemTemplate> <DataTemplate> <!--Legend items (3rd level = last level due to flat option)--> <ContentPresenter Content="{Binding}" ContentTemplate="{Binding Template}" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </DataTemplate> </toolkit:Accordion.ContentTemplate> </toolkit:Accordion> </ScrollViewer> </ControlTemplate> </Setter.Value> </Setter> </Style>
I have the need to categorize dynamic map service layers according to categories that I retrieve from another web service source. It doesn't appear that the legend control currently offers the capability of tagging or categorizing its layer items.From 2.2, a tag property has been added to the LegendItemViewModel class. This property is designed for the scenario you are talking about (you could store your category in this property).
Ideally I would subclass from LayerItemViewModel and introduce a new property, "Category", for example but that class is sealed.
Somehow tag a layer item with a category and use this for categorization.
Intercept legend control refresh events and perform my categorization at that point with my own solution in code. Don't know if Legend.Refresh event is intended for this purpose.
Is there any conceptual level help documentation for toolkit controls beyond the auto-generated stuff at http://help.arcgis.com/en/webapi/sil.../api_start.htm Any help even via this forum dialog would be much appreciated.
The Legend.Refresh event does not fire for all cases as I would expect. My expectation/hope was that whenever any layer was added/removed from the map, the event would fire.
It doesn't fire for all additions or removals of a map layer or change in layerID list. I reverted then to registering for notification of when the Legend's LayerItemsSource dependency property changes which isn't ideal.
I recognize that this is a long post and am hoping to just start some dialog with one of the developers of this control.
The text that you have entered is too long (13167 characters). Please shorten it to 10000 characters long.
This happens:
- after adding a layer: as soon as the legend is available (we get the legend asynchronously).
- when the legend of the map layer has changed (e.g. if the renderer of a feature layer changes).
- when someone calls 'Refresh
None of the notification mechanisms from Legend (Refresh event, LayerItems, LayerItemsSource property changed) do exactly what I want. I'm looking for a way to be notified when I 1)add a layer and 2) remove a layer.
The problem with LayerItems dependency property is it's not updated consistently enough (I know that's vague but it's been a couple weeks since I looked at it).
private void MyLegend_Loaded(object sender, RoutedEventArgs e) { RegisterForNotification("LayerItems", sender as Client.Toolkit.Legend, LayerItemsChanged); } void LayerItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Debug.WriteLine("LayerItems changed count = {0}", (d as Client.Toolkit.Legend).LayerItems.Count()); } /// Listen for change of the dependency property public void RegisterForNotification(string propertyName, FrameworkElement element, PropertyChangedCallback callback) { //Bind to a dependency property Binding b = new Binding(propertyName) { Source = element }; var prop = System.Windows.DependencyProperty.RegisterAttached( "ListenAttached"+propertyName, typeof(object), typeof(UserControl), new System.Windows.PropertyMetadata(callback)); element.SetBinding(prop, b); }
The problem with LayerItemsSource dependency property is it's updated too often.
I believe that the Refresh event would be ideal for me to listen to if it were fired when a layer was removed from the map. Can you consider adding this?
Next question. You gave an excellent explanation of 3 of the classes. They make sense. I'm still confused about the 2 biggie properties on the Legend control, Legend.LayerItems versus Legend.LayerItemsSource. I'm using the control in a flat fashion (no tree structure). In that case, is Legend.LayerItems identical to Legend.LayerItemsSource?
What is the purpose of composing your Legend control with that LegendTree class?
//listens for layer added to legend but not removed base.Refreshed += new EventHandler<RefreshedEventArgs>(BinLegend_Refreshed); //listens for layer removed from layer id collection DependencyPropertyUtilities.RegisterForNotification("LayerIDs", this, LayerIDsChanged);
I have a checkbox SHOW ALL LAYERS that sets ShowOnlyVisibleLayers to false...
The legend is created SYNCRONOUSLY and user cannot do anything while it is being generated.
Dominique, know this is an old thread, are you still around ?