Reputation: 797
I've been searching for a solution to display the indexes of items from a ListView for a few hours. I can't add a new property to the data source, as an index property to bind to the value.
I've been trying to Bind to a Converter:
<DataTemplate x:Key="TubeTemplate" x:DataType="data:Tube">
<local:TubeTemplate HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
FavoritesNumber="{Binding Converter={StaticResource IndexConverter}}"
Closed="TubeTemplate_Closed"></local:TubeTemplate>
</DataTemplate>
This is the Converter:
public sealed class IndexConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var item = (ListViewItem)value;
var listView = ItemsControl.ItemsControlFromItemContainer(item) as ListView;
int index = listView.IndexFromContainer(item) + 1;
return index.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
The issue is that my code breaks at: var item = (ListViewItem)value;
The value I'm getting is the DataType binded to each item, instead of the ListViewItem.
What Am I doing wrong?
Upvotes: 1
Views: 1073
Reputation: 2651
Use {RelativeSource Mode=TemplatedParent} in the Binding. Then, you can get the ItemContainer with the help of VisualTreeHelper as follows.
<local:TubeTemplate ...
FavoritesNumber="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource IndexConverter}}"
.../>
and
public object Convert(object value, Type targetType, object parameter, string language)
{
var presenter = value as ListViewItemPresenter;
var item = VisualTreeHelper.GetParent(presenter) as ListViewItem;
var listView = ItemsControl.ItemsControlFromItemContainer(item);
int index = listView.IndexFromContainer(item) + 1;
return index.ToString();
}
However, index displayed in this way won't be automatically updated on collection changes. So, if you'll remove some items afterwards, you'd have to implement another function to request each item to reload its index.
Upvotes: 4
Reputation: 75
Try using AlternationIndex. Also according to this answer, you should use ListViewItem as RelativeSource
In your case, it would look something like
<DataTemplate>
<TextBlock Text="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource AncestorType=ListViewItem},
StringFormat={}Index is {0}}">
</TextBlock>
</DataTemplate>
Upvotes: 1