WPF ItemsControl the current ListItem Index in the ItemsSource
Is it possible to know the current item's Index in a ItemsControl?
EDIT This works!
<Window.Resources>
<x:Array Type="{x:Type sys:String}" x:Key="MyArray">
<sys:String>One</sys:String>
<sys:String>Two</sys:String>
<sys:String>Three</sys:String>
</x:Array>
</Window.Resources>
<ItemsControl ItemsSource="{StaticResource MyArray}" AlternationCount="100">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10">
<!-- one -->
<TextBlock Text="{Binding Path=.,
StringFormat={}Value is {0}}" />
<!-- two -->
<TextBlock Text="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource TemplatedParent},
FallbackValue=FAIL,
StringFormat={}Index is {0}}" />
<!-- three -->
<TextBlock Text="{Binding Path=Items.Count,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ItemsControl}},
StringFormat={}Total is {0}}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
It looks like this:
I asked the same thing a while ago here
There isn't a built in Index property, but you can set the AlternationCount
of your ItemsControl to something higher than your item count, and bind to the AlternationIndex
<TextBlock Text="{Binding
Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource Mode=TemplatedParent},
FallbackValue=FAIL,
StringFormat={}Index is {0}}" />
It should be noted that this solution may not work if your ListBox uses Virtualization as bradgonesurfing pointed out here.
This is not quite an answer but a suggestion. Do not use the AlternationIndex technique as suggested. It seems to work first off but there are wierd side effects. It seems that you cannot guarantee that the AlternationIndex starts at 0.
On first rendering it works correctly
but re-sizing the Grid and then expanding results in the index not starting at zero any more. You can see the effect in the below image
This was generated from the following XAML. There are some custom components in there but you will get the idea.
<DataGrid
VirtualizingPanel.VirtualizationMode="Recycling"
ItemsSource="{Binding MoineauPumpFlanks.Stator.Flank.Boundary, Mode=OneWay}"
AlternationCount="{Binding MoineauPumpFlanks.Stator.Flank.Boundary.Count, Mode=OneWay}"
AutoGenerateColumns="False"
HorizontalScrollBarVisibility="Hidden"
>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Id">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Margin="0,0,5,0"
TextAlignment="Right"
Text="{Binding RelativeSource={ RelativeSource
Mode=FindAncestor,
AncestorType=DataGridRow},
Path=AlternationIndex}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn >
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Point ["/>
<Controls:DisplayUnits DisplayUnitsAsAbbreviation="True" DisplayUnitsMode="Length"/>
<TextBlock Text="]"/>
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Controls:LabelForPoint ShowUnits="False" Point="{Binding}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
I am searching for an alternate solution :(