Search code examples
c#wpfwpf-controlsivalueconverterwpf-style

Using ValueConverter in Style DataTrigger of ItemsControl but List is Empty


I am attempting to use a ValueConverter to flip the last item in an ItemsControl (so that it appears backwards).

To accomplish this, I created a Style with a DataTrigger which is using a ValueConverter to check if the current item is the last item in the list.

<UserControl.Resources>
  <local:FIsLastItemInContainerConverter x:Key="IsLastItemInContainerConverter"/>
</UserControl.Resources>

<StackPanel>
  <ItemsControl ItemsSource="{Binding Path=ActiveAction.ActionIconDatas}">
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <DataTemplate.Resources>
          <Style TargetType="local:FActionInfoControl">
            <Style.Triggers>
              <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource IsLastItemInContainerConverter}}" Value="True">
                <Setter Property="RenderTransformOrigin" Value="0.5 0.5"/>
                <Setter Property="RenderTransform">
                  <Setter.Value>
                    <TransformGroup>
                      <ScaleTransform ScaleX="-1"/>
                    </TransformGroup>
                  </Setter.Value>
                </Setter>
              </DataTrigger>
            </Style.Triggers>
          </Style>
        </DataTemplate.Resources>
        <ContentControl>
          <local:FActionInfoControl/>
        </ContentControl>
      </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
  </ItemsControl>
</StackPanel>

The issue appears to be with my ValueConverter.

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    DependencyObject item = (DependencyObject)value;

    // THIS IS RETURNING NULL
    ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item);

    if (ic == null)
    {
        return false;
    }
    else
    {
        return ic.ItemContainerGenerator.IndexFromContainer(item) == ic.Items.Count - 1;
    }
}

Although item is a valid element in the ItemsControl, the call to ItemsControl.ItemsControlFromItemContainer is returning null and I'm not sure why. It is being set, and displays fine (it just is never flipped as the style should cause it to).

Any ideas on this? Thanks!


Solution

  • Try replacing your binding with:

    {Binding RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}, AncestorLevel=2}, Converter={StaticResource IsLastItemInContainerConverter}}
    

    Actually ItemsControl.ItemsControlFromItemContainer() only returns parent ItemsControl for actual item containers. In your case ContentPresenter is the container type as you use simple ItemsControl. However as you incapsulate your in a ContentControl in your data template it is important to specify AncestorLevel=2 as well.