Question

I'm trying to display an array in a DataGrid like this:

XAML:

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" >
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Index" IsReadOnly="True">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Items, Path=}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Name" IsReadOnly="True">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Items, Path=Name}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

The Name column works as expected, but I'm wondering if there is a way to display the index of the current element in the collection in the Index column so I don't have to have that as a data item in the collection itself.

Was it helpful?

Solution

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. ;)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top