4 Replies Latest reply on Apr 11, 2012 10:19 AM by schinks

    Default to collapsed legend items

    schinks
      Hi,

      Is there a property I can set so that items in the legend default to collapsed?  I am using the legend in tree mode and consuming a map service that has 30 layers in it.  When the layer loads the tree node expands and I can't find a way to prevent this (short of using control templates). 

      Thanks,
      Cory
        • Re: Default to collapsed legend items
          schinks
          Mike,

          Thanks for your response.  I considered handling the legend refreshed event, however I am using MVVM and that approach does not work well with the pattern.  I may have a way to get around the MVVM issue, but it's not ideal.  Do you have any suggestions on how to handle the event while maintaining strict adherence to MVVM (no code-behind)?

          Thanks,
          Cory
          • Re: Default to collapsed legend items
            kuiperfoliage
            Mike,

            Thanks for your response.  I considered handling the legend refreshed event, however I am using MVVM and that approach does not work well with the pattern.  I may have a way to get around the MVVM issue, but it's not ideal.  Do you have any suggestions on how to handle the event while maintaining strict adherence to MVVM (no code-behind)?

            Thanks,
            Cory


            I guess you would be able to solve this by implementing a WPF behavior using attached properties.
            • Re: Default to collapsed legend items
              schinks
              A colleague and I came up with a solution to this problem. I wanted to use EventTriggers to handle the Legend Refresh event in my ViewModel, the problem is that EventTriggers do not support passing EventArgs. That is another topic all together, why event args are not passed with the EventTrigger. Anyway, my colleague extended the EventTrigger so that it supports passing the event args and it works great.

              I will attempt to explain how it all comes together. In the view, a trigger is added to the legend control:
              <esri:Legend Map="{Binding ElementName=MyMap}"[INDENT]LayerItemsMode="Tree"> <i:Interaction.Triggers>[/INDENT] [INDENT=2]<i:EventTrigger EventName="Refreshed" >[/INDENT] [INDENT=3]<Commands:InvokeCommandActionWithArgs Command="{Binding LegendRefreshedCommand}" />[/INDENT] [INDENT=2]</i:EventTrigger>[/INDENT] [INDENT]</i:Interaction.Triggers>[/INDENT] </esri:Legend>


              The key thing to notice here is Commands:InvokeCommandActionWithArgs. This is an extended version of TriggerAction and looks like:
              public class InvokeCommandActionWithArgs : TriggerAction<DependencyObject>     {         public static DependencyProperty CommandProperty =         DependencyProperty.Register("Command", typeof(ICommand),                                     typeof(InvokeCommandActionWithArgs));          public ICommand Command         {             get { return GetValue(CommandProperty) as ICommand; }             set { SetValue(CommandProperty, value); }         }                   protected override void Invoke(object parameter)         {             if (Command == null) return;             Command.Execute(parameter);         }     }


              Also notice in the view that the command binding for the Triggeraction is Command="{Binding LegendRefreshedCommand}" . LegendRefreshedCommand is defined in our ViewModel which looks something like:

              public class MainWindowViewModel    {          public ICommand LegendRefreshedCommand { get; private set; }          public MainWindowViewModel()         {             LegendRefreshedCommand = new RelayCommand<Legend.RefreshedEventArgs>(OnLegendRefresh, null);         }                  private void OnLegendRefresh(Legend.RefreshedEventArgs refreshedEventArgs)         {             refreshedEventArgs.LayerItem.IsExpanded = false;         }     }


              When the Refreshed event on the legend is bound to the LegendRefreshedCommand on the viewmodel via the extended TriggerAction the OnLegendRefresh method will handle the event. The RefreshedEventArgs are passed in and the LayerItem can now be accessed and the IsExpanded property set to false. This is the piece that is missing when using the plain EventTrigger, because it does not pass the event args.

              Hopefully that all makes sense and is easy to follow. I have attached a very simple reference project that might make it more clear.