Can legenditems (symbology and label) be displayed in a control of other than a legend, I assume so?
It seems to work as far as, the first messagebox displays the sublayer name and the second message box shows the label for the unique values in the legend if the layer is visible.
So...how can i put the label and its symbology in my columns?
In your code legItems.Label and legeItems.ImageSource are the label and it's symbology, so you could store them in your own collection and display them in your own control other than a legend. Nevertheless, the easiest way seems to retemplate the legend control by using a WrapPanel (needs the toolkit). Something like:
<Style x:Key="WrapPanel" TargetType="esri:Legend">
<Setter Property="LayerItemsMode" Value="Flat" />
<Setter Property="ShowOnlyVisibleLayers" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="esri:Legend">
<ListBox x:Name="listBox" ItemsSource="{TemplateBinding LayerItemsSource}"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Controls:WrapPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<!--Layer Item-->
<ContentPresenter Content="{Binding}" ContentTemplate="{Binding Template}" />
<!--Legend Items-->
<ItemsControl ItemsSource="{Binding LegendItems}">
<ItemsControl.ItemTemplate>
<DataTemplate >
<ContentPresenter Content="{Binding}" ContentTemplate="{Binding Template}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
With this legend style, the main listbox is using a wrap panel to organize the items, one item being itself a listbox with all swatches of a sublayer. You might want not to see the sublayers but only the swatches. This style with only one level of listbox shoud help:
<local:SelectManyLegendItems x:Key="selectManyLegendItems" />
<Style x:Key="WrapPanelItems" TargetType="esri:Legend">
<Setter Property="LayerItemsMode" Value="Flat" />
<Setter Property="ShowOnlyVisibleLayers" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="esri:Legend">
<ListBox x:Name="listBox" ItemsSource="{Binding LayerItemsSource, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource selectManyLegendItems}}"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Controls:WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<ContentPresenter Content="{Binding}" ContentTemplate="{Binding Template}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The issue with this style is that we need to initialize the ItemsSource of the listbox with all swatches (i.e. all legendItems) of all sublayers. This can easily be done by using the LINQ 'SelectMany' in a converter.Code of the converter:
public sealed class SelectManyLegendItems : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (value as IEnumerable<LegendItemViewModel>).OfType<LayerItemViewModel>().SelectMany(layerItem => layerItem.LegendItems);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw (new Exception(string.Format("Not implemented or Bad usage of {0}", GetType().Name)));
}
}
Hope this help.