There are a couple of difficulties here. First, here is my markup:
<ItemsControl x:Name="TaskBarItems">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Converter={StaticResource groupName}}"
FontWeight="Bold" />
<ItemsControl ItemsSource="{Binding}"
Margin="12 0 0 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding DisplayName}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
and my Shell:
public class ShellViewModel : IShell
{
readonly TaskBarItemViewModel[] taskBarItems;
public ShellViewModel()
{
taskBarItems = new[]
{
new TaskBarItemViewModel {GroupName = "Animal", DisplayName = "Monkey"},
new TaskBarItemViewModel {GroupName = "Animal", DisplayName = "Cat"},
new TaskBarItemViewModel {GroupName = "Animal", DisplayName = "Dog"},
new TaskBarItemViewModel {GroupName = "Mineral", DisplayName = "Biotite"},
new TaskBarItemViewModel {GroupName = "Mineral", DisplayName = "Phlogopite"},
new TaskBarItemViewModel {GroupName = "Mineral", DisplayName = "Lepidolite"},
};
}
public IEnumerable<IGrouping<string, TaskBarItemViewModel>> TaskBarItems
{
get
{
return taskBarItems.GroupBy(t => t.GroupName).ToList();
}
}
}
Calibrun Micro (cm) will bind the itemscontrol, TaskBarItems, by convention. However, the rest won't work by convention for a couple of reasons. It's in a DataTemplate, so we would usually use Bind.Model. However, it won't work here because the type of each item in the itemscontrol is generic (IGrouping). The default conventions can't handle finding a view for that. So we provide a data template inline.
Secondly, the Key property appears to be implemented as an explicit interface. That means Silverlight can't bind to it. I made a simple converter that binds to the group and extracts the key:
public class GroupNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((IGrouping<string,TaskBarItemViewModel>)value).Key;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Next, since the grouping is itself the IEnumerable we have to bind the ItemsSource of the nested itemscontrol directly. We can't use conventions because there is not property on IGrouping that returns the items. (Though if there was, we'd probably still have the explicit interface issue.)
Regarding your second question. You can bind an action to any event. See the documentation here:
http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions&referringTitle=Documentation