WPF Datagrid Index problem

Nov 5, 2010 at 8:06 PM

I can't seem to get my head around this.

I've created sample code to demo my issue, hoping someone can direct me to the answer...

The issue is once the datagrid is sorted, the labeled ID and Name no longer matches the selected datagrid item.

I would appriciate your assistance...

Thanks

Jeff

<Window x:Class="dgSortTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="dgSortTest" Height="253" Width="403" IsEnabled="True">
    <Grid>
        <DataGrid AutoGenerateColumns="False" Height="212" HorizontalAlignment="Left" Margin="12,2,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="200" SelectionChanged="dataGrid1_SelectionChanged" RowHeaderWidth="0" AreRowDetailsFrozen="False" CanUserAddRows="True" CanUserDeleteRows="True" IsReadOnly="True">
            <DataGrid.Columns>
                <DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        </DataGrid.Columns>
        </DataGrid>
        <Label Content="Index: " Name="lblIndex" Height="28" HorizontalAlignment="Left" Margin="228,12,0,0" VerticalAlignment="Top" Width="92" />
        <Label Content="ID:" Name="lblID" Height="28" HorizontalAlignment="Left" Margin="228,46,0,0" VerticalAlignment="Top" Width="141" IsEnabled="True" />
        <Label Content="Name: " Name="lblName" Height="28" HorizontalAlignment="Left" Margin="228,80,0,0" VerticalAlignment="Top" Width="141" />
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace dgSortTest
{
    public partial class MainWindow : Window
    {
       List<Person> people = new List<Person>();
       public MainWindow()
        {
            InitializeComponent();
            people.Add(new Person() { ID = 0, Name = "Jeff" });
            people.Add(new Person() { ID = 1, Name = "Tom" });
            people.Add(new Person() { ID = 2, Name = "Andy" });
            people.Add(new Person() { ID = 3, Name = "Ken" });
            people.Add(new Person() { ID = 4, Name = "Zack" });
            people.Add(new Person() { ID = 5, Name = "Emily" });
            people.Add(new Person() { ID = 6, Name = "Courtney" });
            people.Add(new Person() { ID = 7, Name = "Adam" });
            people.Add(new Person() { ID = 8, Name = "Brenda" });
            people.Add(new Person() { ID = 9, Name = "Bill" });
            people.Add(new Person() { ID = 10, Name = "Joan" });
            dataGrid1.ItemsSource = from Person in people select Person;
        }

        private void dataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            int index = dataGrid1.SelectedIndex;
            lblIndex.Content = "Index: " + index.ToString();
            lblID.Content = "ID: " + people[index].ID;
            lblName.Content = "Name: " + people[index].Name;
        } 
    }

    public class Person
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}


Nov 11, 2010 at 11:50 PM

This was a responce on another blog, that solved my issue.

Short answer, to not change to much of your current implementation you can do this.

private void dataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
   
Person selectedItem = dataGrid1.SelectedItem as Person;
   
int index = dataGrid1.SelectedIndex;
    lblIndex
.Content = "Index: " + index.ToString();
    lblID
.Content = "ID: " + selectedItem.ID;
    lblName
.Content = "Name: " + selectedItem.Name;
}

However, I would advice you to bind directly to the SelectedItem instead. Then you won't need the code behind EventHandler.

<StackPanel Orientation="Vertical" Margin="228,12,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="92" >
   
<StackPanel Orientation="Horizontal">
       
<TextBlock Text="Index: "/>
       
<TextBlock Text="{Binding ElementName=dataGrid1, Path=SelectedIndex}"/>
   
</StackPanel>
   
<StackPanel Orientation="Horizontal">
       
<TextBlock Text="ID: "/>
       
<TextBlock Text="{Binding ElementName=dataGrid1, Path=SelectedItem.ID}"/>
   
</StackPanel>
   
<StackPanel Orientation="Horizontal">
       
<TextBlock Text="Name: "/>
       
<TextBlock Text="{Binding ElementName=dataGrid1, Path=SelectedItem.Name}"/>
   
</StackPanel>
</StackPanel>