I've created this just now.
<DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False" Name="DGrid">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Index" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Tag="{Binding}" Loaded="TextBlock_Loaded" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Name" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
And the code-behind:
public partial class MainWindow : Window
{
List<Item> items = new List<Item>();
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 10; i++)
items.Add(new Item() { Name = Guid.NewGuid().ToString() });
DGrid.DataContext = items;
}
private void TextBlock_Loaded(object sender, RoutedEventArgs e)
{
var block = sender as TextBlock;
var item = block.Tag as Item;
block.Text = items.IndexOf(item).ToString();
}
}
public class Item
{
public string Name { get; set; }
}
It's not a pretty solution, but it works. If you'd prefer to use bindings rather than events, I guess you could create a reference to the collection containing the Item
inside the Item
itself, and then create a property which would return the index, like so:
public class Item
{
public List<Item> ItemCollection { get; set; }
public string Index
{
get
{
return ItemCollection.IndexOf(this).ToString();
}
}
public string Name { get; set; }
}
and then modify two lines:
items.Add(new Item() { Name = Guid.NewGuid().ToString(), ItemCollection = items });
and
<TextBlock Text="{Binding Index}" />
I'll be honest - I'm not sure if this is the best way to do this. ;)