Привязка списка в WPF с группировкой - PullRequest
2 голосов
/ 08 апреля 2010

У меня есть коллекция ViewModels и я хочу привязать к ним ListBox. Проводя некоторое расследование, я обнаружил это .

Итак, моя ViewModel выглядит так (псевдокод)

interface IItemViewModel 
{
 string DisplayName { get; }
}

class AViewModel : IItemViewModel 
{
 string DisplayName { return "foo"; }
}

class BViewModel : IItemViewModel 
{
 string DisplayName { return "foo"; } 
}

class ParentViewModel 
{
 IEnumerable<IItemViewModel> Items 
 {
  get
  {
   return new IItemViewModel[] {
    new AItemViewModel(),
    new BItemViewModel()
   }
  }
 }
}

class GroupViewModel 
{
 static readonly GroupViewModel GroupA = new GroupViewModel(0);
 static readonly GroupViewModel GroupB = new GroupViewModel(1);

 int GroupIndex;
 GroupViewModel(int groupIndex) 
 {
  this.GroupIndex = groupIndex;
 }

 string DisplayName
 {
  get { return "This is group " + GroupIndex.ToString(); }
 }
}

class ItemGroupTypeConverter : IValueConverter
{
 object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 {
  if (value is AItemViewModel)
   return GroupViewModel.GroupA;
  else 
   return GroupViewModel.GroupB;
 }
}

А это XAML

<UserControl.Resources>
 <vm:ItemsGroupTypeConverter x:Key="ItemsGroupTypeConverter "/>
 <CollectionViewSource x:Key="GroupedItems" Source="{Binding Items}">
  <CollectionViewSource.GroupDescriptions>
   <PropertyGroupDescription Converter="{StaticResource ItemsGroupTypeConverter }"/>
  </CollectionViewSource.GroupDescriptions>
 </CollectionViewSource>
</UserControl.Resources>
<ListBox ItemsSource="{Binding Source={StaticResource GroupedItems}}">
 <ListBox.GroupStyle>
  <GroupStyle>
   <GroupStyle.HeaderTemplate>
    <DataTemplate>
     <TextBlock Text="{Binding DisplayName}" FontWeight="bold" />
    </DataTemplate>
   </GroupStyle.HeaderTemplate>
  </GroupStyle>              
 </ListBox.GroupStyle>
 <ListBox.ItemTemplate>
  <DataTemplate>
   <TextBlock Text="{Binding DisplayName}" />
  </DataTemplate>
 </ListBox.ItemTemplate>
</ListBox>

Это работает как-то, за исключением того факта, что привязка HeaderTemplate не работает. В любом случае, я бы предпочел опустить TypeConverter и CollectionViewSource. Разве нет способа использовать свойство ViewModel для группировки?

Я знаю, что в этом примере сценария было бы легко заменить GroupViewModel строкой, если она работает, но это не вариант. Так как же я могу привязать шаблон HeaderTemplate к GroupViewModel?

1 Ответ

10 голосов
/ 08 апреля 2010

Хорошо, я наконец-то решил это сам.

Прежде всего, TypeConverter не нужен, потому что PropertyGroupDescription может быть привязано к PropertyName. Поэтому я добавил свойство «Группа» в IItemViewModel и изменил XAML следующим образом:

<UserControl.Resources>
 <CollectionViewSource x:Key="GroupedItems" Source="{Binding Items}">
  <CollectionViewSource.GroupDescriptions>
   <PropertyGroupDescription PropertyName="Group"/>
  </CollectionViewSource.GroupDescriptions>
 </CollectionViewSource>
</UserControl.Resources>

Кроме того, DataContext HeaderTemplate является CollectionViewGroupInternal, и привязка должна выглядеть следующим образом:

<DataTemplate>
 <TextBlock Text="{Binding Name.DisplayName}" FontWeight="bold" />
</DataTemplate>

Здесь CollectionViewGroupInternal.Name разрешает фактическую GroupViewModel.

...