3

I want to bind an ItemsControl to an array of object, using ItemsSource and DataTemplate. And I want to show the index of each item. Like

Customer 1:

Name: xxxx

Age:888

Customer 2:

Name: yyy

Age: 7777

1 Answer 1

6

The simplest way to do this is to add an Index property to you class ;-) Otherwise it can be done using a MultiValueConverter:

<Window x:Class="IndexSpike.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" xmlns:Converters="clr-namespace:IndexSpike" xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase" Name="Root" > <Window.Resources> <Converters:GetIndex x:Key="GetIndexConverter"/> </Window.Resources> <StackPanel> <ItemsControl ItemsSource="{Binding Persons}"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Margin="0,5,0,0"> <TextBlock.Text> <MultiBinding Converter="{StaticResource GetIndexConverter}" StringFormat="Index: {0}"> <Binding Path="."/> <Binding ElementName="Root" Path="Persons"/> </MultiBinding> </TextBlock.Text> </TextBlock> <TextBlock Text="{Binding Name, StringFormat='Name: {0}'}"/> <TextBlock Text="{Binding Age, StringFormat='Age {0}'}"/> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </StackPanel> </Window> using System; using System.Collections.ObjectModel; using System.Globalization; using System.Windows; using System.Windows.Data; namespace IndexSpike { public partial class Window1 : Window { public ObservableCollection<Person> Persons { get; set; } public Window1() { Persons=new ObservableCollection<Person> { new Person("Me",20), new Person("You",30) }; InitializeComponent(); DataContext = this; } } public class Person { public Person(string name,int age) { Name = name; Age=age; } public string Name { get; set; } public int Age { get; set; } } public class GetIndex:IMultiValueConverter { #region Implementation of IMultiValueConverter public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { var persons = (ObservableCollection<Person>) values[1]; var person = (Person) values[0]; return persons.IndexOf(person); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } #endregion } } 

Thanks to this question I found an other way to declare the MultiBinding:

<MultiBinding Converter="{StaticResource GetIndexConverter}" StringFormat="Index: {0}"> <Binding Path="."/> <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}" Path="DataContext.Persons"/> </MultiBinding> 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.