Search code examples
wpfitemscontrolcontentpresenter

Unable to set ContentPresenter Grid.Row Index using AlternationIndex in ItemsControl


I'm trying to set Grid.Row value using AlternationIndex to make ContentPressenter in correct position. But it seems to not able to bind ItemsControl.AlternationIndex for ContentPresenter in style. I can access ItemsControl.AlternationIndex via style trigger, but unable to access via binding. Any ideas how to access ItemsControl.AlternationIndex for ContentPresenter? The following code is a simple demostration for this question.

MainWindow.xaml

<Window x:Class="ContentPresenterIndex.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ContentPresenterIndex"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ItemsControl ItemsSource="{Binding NameList}" AlternationCount="{Binding NameList.Count}">
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="{x:Type ContentPresenter}">
                    <Setter Property="Grid.Row" Value="{Binding ItemsControl.AlternationIndex, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"/>
                <Setter Property="Grid.Row" Value="{Binding ItemsControl.AlternationIndex, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"/>
                <!--<Style.Triggers> <----- this is ok
                    <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                        <Setter Property="Grid.Row" Value="1"/>
                    </Trigger>
                </Style.Triggers>-->
            </Style>
                </Style>
            </ItemsControl.ItemContainerStyle>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Grid IsItemsHost="True">
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                    </Grid>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Name}" Grid.Column="0"/>
                        <TextBlock Text="{Binding Age}" Grid.Column="1"/>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

MainWindow.xaml.cs

namespace ContentPresenterIndex
{
    public class NameItem
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

    public partial class MainWindow : Window
    {
        public ObservableCollection<NameItem> NameList { get; set; }
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;

            NameList = new ObservableCollection<NameItem>
            {
                new NameItem { Name = "John", Age = 20 },
                new NameItem { Name = "Jane", Age = 21 },
                new NameItem { Name = "Davie", Age = 22 },
                new NameItem { Name = "Robert", Age = 23 }
            };
        }
    }
}

Solution

  •  <ItemsControl.ItemContainerStyle>
                    <Style TargetType="{x:Type ContentPresenter}">
                        <Setter Property="Grid.Row" Value="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}}" />
                    </Style>
                </ItemsControl.ItemContainerStyle>