Здесь есть пара трудностей. Во-первых, вот моя разметка:
<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>
и моя раковина:
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) будет связывать элементы управления TaskBarItems по соглашению. Тем не менее, остальные не будут работать по соглашению по нескольким причинам. Он находится в DataTemplate, поэтому мы обычно используем Bind.Model. Однако это не сработает, потому что тип каждого элемента в itemscontrol является общим (IGrouping). Соглашения по умолчанию не могут обработать поиск представления для этого. Поэтому мы предоставляем встроенный шаблон данных.
Во-вторых, свойство Key представляется реализованным как явный интерфейс. Это означает, что Silverlight не может связываться с ним. Я сделал простой конвертер, который привязывается к группе и извлекает ключ:
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();
}
}
Далее, поскольку группировка сама по себе является IEnumerable, мы должны напрямую связать ItemsSource вложенного элемента управления. Мы не можем использовать соглашения, потому что в IGrouping нет свойства, которое возвращает элементы. (Хотя, если бы было, у нас, вероятно, все еще была бы явная проблема с интерфейсом.)
Относительно вашего второго вопроса. Вы можете привязать действие к любому событию. Смотрите документацию здесь:
http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions&referringTitle=Documentation