1

我的情况很奇怪。我正在生成按特定类别分组的项目列表。在我的视图模型中,我将项目存储在 的实例中ReadOnlyDictionary<string, List<CustomObject>>,其中CustomObject表示我为存储每个列表项而创建的类。字符串是类别。在我看来,我有一个StackPanel<ItemsControl>里面。项目控件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。我想即使是这样,它也无法知道是哪个项目在调用它。

所以。我该怎么办?

4

2 回答 2

0

您无需在 VM 中添加新属性或使用ItemTemplateSelector.

我宁愿将它单独保存在 xaml 中,因为它只是与视图相关,与任何需要“测试”的逻辑无关

因此,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相同ListBoxItemSource.Count从而AlternationIndex在每个 上生成一个唯一的ListBoxItem
  • DataTemplate.DataTrigger只需检查当前项目以查看它是否AlternationIndex为 0,如果是则隐藏seperator.
于 2013-07-06T17:52:50.533 回答
0

我会采用 MVVM 方法:

  1. CustomObjectViewModel保存在您的 Dictionary 而不是您的 CustomObject 中,并将您的CustomObject 作为它的 Model

  2. 在 CustomObjectViewModel 中可以访问CustomObjectService(或为简单起见对 Dictionary 的引用)。

  3. 在提到的服务中,有一个类似的方法:

    Public Boolean IsCustomObjectFirst(CustomObjectViewModel vm){..}

    显然,这将检查给定项目的位置。

  4. 现在只需ShouldDisplaySeperator在您的CustomObjectViewModel中有一个属性,它将从中获得它的价值CustomObjectService.IsCustomObjectFirst(this)

  5. 现在只需在您的视图定义中使用它,使用类似于:

    查看定义:

    <DataTemplate x:Key="DataTemplateName">
        <StackPanel>
            <Separator Visibilty="{Binding ShouldDisplaySeperator,Converter={StaticResource BooleanToVisibilityConverter}}" />
            <TextBlock Text="{Binding Model.Key}" />
            <ItemsControl ItemsSource="{Binding Model.Value}" />
        </StackPanel>
    </DataTemplate>
    
于 2013-07-06T17:46:00.253 回答