我处境很奇怪。我正在生成按特定类别分组的项目列表。在我的视图模型中,我将项目存储在ReadOnlyDictionary<string, List<CustomObject>>
的实例中,其中CustomObject
表示我为存储每个列表项而创建的类。字符串是类别。在我看来,我的StackPanel
里面有一个<ItemsControl>
。 items控件有一个ItemTemplate
,如下所示:
<DataTemplate x:Key="DataTemplateName">
<StackPanel>
<Separator />
<TextBlock Text="{Binding Key}" />
<ItemsControl ItemsSource="{Binding Value}" />
</StackPanel>
</DataTemplate>
上面的绑定工作得很好。问题是我不希望第一个项目上方有分隔符。所以我想第一个项目我需要一个不同的风格。
我尝试使用ItemTemplateSelector
,但问题是它只能访问当前项,因此无法知道它是否在第一个元素上。我也尝试过像
<Separator
Visibility={Binding ShowSeparator, RelativeSource={RelativeSource AncestorType={x:Type CustomObject}}}" />
...其中ShowCategories是CustomObject类中的依赖项属性,它查看ReadOnlyDictionary实例并说明是否显示分隔符。但是,当我这样做时,从不访问ShowCategories。我想即使它是,它也无法知道哪个项目正在调用它。
因此。我该怎么办?
答案 0 :(得分:0)
我会选择MVVM方法:
将 CustomObjectViewModel 保留在Dictionary中而不是CustomObject中,并使用 CustomObject作为其模型。
在CustomObjectViewModel中,可以访问 CustomObjectService (或为了简单起见,对字典的引用)。
在上述服务中,有一个类似于:
的方法 Public Boolean IsCustomObjectFirst(CustomObjectViewModel vm){..}
显然,这将检查给定项目的位置。
现在只需在 CustomObjectViewModel 中添加一个属性ShouldDisplaySeperator
即可从CustomObjectService.IsCustomObjectFirst(this)
现在只需在View的定义中使用它,使用类似于:
的内容查看定义:
<DataTemplate x:Key="DataTemplateName">
<StackPanel>
<Separator Visibilty="{Binding ShouldDisplaySeperator,Converter={StaticResource BooleanToVisibilityConverter}}" />
<TextBlock Text="{Binding Model.Key}" />
<ItemsControl ItemsSource="{Binding Model.Value}" />
</StackPanel>
</DataTemplate>
答案 1 :(得分:0)
您可以执行此操作,而无需在VM中添加新属性或使用ItemTemplateSelector
。
我更喜欢将它保留在xaml中,因为它只是View相关而且与任何需要“测试”的逻辑无关
因此xaml解决方案可能是使用ItemsControl.AlternationIndex
类似的东西:
<ListBox AlternationCount="{Binding RelativeSource={RelativeSource Self}, Path=ItemsSource.Count, Mode=OneWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Separator x:Name="seperator" />
<TextBlock Text="{Binding Key}" />
<ItemsControl ItemsSource="{Binding Value}" />
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=(ListBox.AlternationIndex),
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListBoxItem}}}"
Value="0">
<Setter TargetName="seperator"
Property="Visibility"
Value="Hidden" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
此代码段的两个关键部分。
AlternationCount
上的ListBox
指定为与ItemSource.Count
相同的AlternationIndex
,从而在每个ListBoxItem
上生成唯一的DataTemplate.DataTrigger
。AlternationIndex
只检查当前项目以查看seperator
是否为0,如果是,则隐藏{{1}}。