使用分组在WPF中绑定列表框

时间:2010-04-07 20:26:51

标签: wpf binding listbox grouping

我有一个ViewModel集合,想要将ListBox绑定到它们。我做了一些调查,发现this

所以我的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 个答案:

答案 0 :(得分:10)

好的,我终于自己解决了。

首先,TypeConverter是不必要的,因为PropertyGroupDescription可以绑定在PropertyName上。所以我在IItemViewModel中添加了一个Property'Group'并修改了XAML,如下所示:

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

此外,HeaderTemplate的DataContext是一个CollectionViewGroupInternal,绑定必须如下所示:

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

这里CollectionViewGroupInternal.Name解析实际的GroupViewModel。