Select to view content in your preferred language

Silverlight Legend Control - changing data templates dynamically

1455
2
10-12-2011 09:38 PM
AndrewBiggins
Occasional Contributor
Hi,

I am using the legend control and have set up a MapLayerTemplate, LayerTemplate and LegendItemTemplate to control how the legend items are drawn. This is working fine, but now I am trying to create a different template for graphics layers in the map, so I can add a right-click context menu that appears only when clicking on graphics layers.

I can see three approaches to this, but I can't see how to get any of them to work:

1. Set up multiple templates in XAML (It looks as if this will be supported in Silverlight 5, but can this be done somehow at version 4?).
2. Change the data template in code behind.
3. Bind data template elements in XAML and use a valueconverter to set visibility property.

I can't see how to do the first two approaches, but I have found some silverlight examples that try the third approach (e.g. http://forums.silverlight.net/t/215879.aspx), so I have tried this in the code below. Unfortunately it doesn't work and the valueconverter code doesn't get called at all.

XAML code:
<UserControl.Resources>
    <ahelp:ContextMenuVisibilityConverter x:Key="VisibilityConverter" />
</UserControl.Resources>

...

<esri:Legend.MapLayerTemplate>
 <DataTemplate>
  <Grid Width="210" Height="Auto" >
   <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition />
   </Grid.ColumnDefinitions>
   <CheckBox Content="{Binding Label}"
       IsChecked="{Binding IsEnabled, Mode=TwoWay}"
       IsEnabled="True" HorizontalAlignment="Left" Grid.Column="0" >
   </CheckBox>
   <Slider Maximum="1" Value="{Binding Layer.Opacity,Mode=TwoWay}" Width="60" Margin="5,0,0,0" HorizontalAlignment="Right" Grid.Column="1" ></Slider>
   <toolkit:ContextMenuService.ContextMenu>
    <toolkit:ContextMenu Name="LayerContextMenu">
     <toolkit:MenuItem Name="ZoomToLayerContextMenuItem" Header="Zoom to Layer" Visibility="{Binding Name, Converter={StaticResource VisibilityConverter}, ConverterParameter=Name}">
      <toolkit:MenuItem.Icon>
       <Image Source="UserControls/Images/ZoomInSmall.png" Stretch="None"  Margin="0" />
      </toolkit:MenuItem.Icon>
     </toolkit:MenuItem>
     <toolkit:Separator Name="SeparatorContextMenuItem" />
     <toolkit:MenuItem Name="RemoveLayerContextMenuItem" Header="Remove Layer">
      <toolkit:MenuItem.Icon>
       <Image Source="UserControls/Images/RemoveLayerSmall.png" Stretch="None" Margin="0" />
      </toolkit:MenuItem.Icon>
     </toolkit:MenuItem>
    </toolkit:ContextMenu>
   </toolkit:ContextMenuService.ContextMenu>
  </Grid>
 </DataTemplate>
</esri:Legend.MapLayerTemplate>


C# code behind:
public class ContextMenuVisibilityConverter : IValueConverter
{

 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  string valueString = value as string;
  if (valueString.Contains("GraphicsLayer"))
   return Visibility.Visible;
  else
   return Visibility.Collapsed;

 }

 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
  throw new NotImplementedException();
 }
}


In the XAML code, can the following line be changed so the valueconverter is called and the name of the layer is passed?
Visibility="{Binding Name, Converter={StaticResource VisibilityConverter}, ConverterParameter=Name}"


Any help would be much appreciated!

Cheers,
Andrew
0 Kudos
2 Replies
DominiqueBroux
Esri Frequent Contributor
I think your issue is coming from your binding to 'Name' :

Visibility="{Binding Name, Converter={StaticResource VisibilityConverter}, ConverterParameter=Name}"


The datacontext of a layer legend item is set to a LayerItemViewModel object. So you have to use one property of this object : see doc. As you can see, there is no 'Name' property but a 'Label' or a 'Layer' property.

Depending on your need a binding to Label or to Layer.ID may work.

You can also just bind to Layer and change your converter to accept a layer as input:
 
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
   return value is GraphicsLayer ? Visibility.Visible : Visibility.Collapsed;
 }
 

So your code is no more depending on labels or IDs.
0 Kudos
AndrewBiggins
Occasional Contributor
Hi Dominique,

Awesome, thank you!

Changing the XAML visibility code to use 'Layer' instead of 'Name' worked, so I now have a right-click context menu just for graphics layers.
Visibility="{Binding Layer, Converter={StaticResource VisibilityConverter}, ConverterParameter=Layer}"


Cheers,
Andrew
0 Kudos