我有一个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?
答案 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。