DataGrid selectedindex when underlying collection changes

Oct 15, 2008 at 8:32 PM
Hi,

I have the DataGrid CTP and I update the ObservableCollection that it is associated with by adding and removing items to it.  What I am seeing is that the grid always sets the selectedindex to zero any time any items are added or removed.

Is there any way to keep the selected index (or selected item the same - even when items are added / removed from the underlying collection)?

Thanks,
Jon

Coordinator
Oct 17, 2008 at 11:04 PM
I'm not seeing this issue at all.  Could you explain more on how you are setting the ItemsSource and how you are doing the add/remove.
Dec 1, 2008 at 1:16 PM
Hi! I see the same thing in my app.

I've bound the Itemssource to DataTable.DefaultView. When I refresh the datatable the selected index jumps back to the first line. How should I prevent the DataGrid from selecting index 0 after a refresh, or even better, keep the old index?
(SelectionUnit=FullRow)

Larsi 
Dec 1, 2008 at 1:40 PM
Hi,

The WPF binding framework constructs a view which wraps your data, adding functionality like sorting, grouping and currency (i.e. selected items). Certain operations will destroy the state held in teh view, such as deleting the data that is wrapped then reconstructing it.

As Vincent mentioned above, how are you refreshing your data?

Colin E.
--
http://wpfadventures.wordpress.com/ - my WPF blog
http://www.codeproject.com/KB/WPF/WPFDataGridExamples.aspx - WPF DataGrid Practical Examples
Dec 1, 2008 at 3:05 PM
Replacing the entire DataTable.

void UpdateDate(DataTable myNewDataTable)
{
MyDataView =  (BindingListCollectionView)CollectionViewSource.GetDefaultView(myNewDataTable.DefaultView);
}
Dec 1, 2008 at 3:18 PM
Hi,

Well ... that's your problem. How is the binding framework supposed to know that you have replaced the binding with a refreshed copy of the same data?

If you are going to do this - you will have to record the selection state before your replace the DataTable, then re-apply it afterwards.

Regards,
Colin E.
--
http://wpfadventures.wordpress.com/ - my WPF blog
http://www.codeproject.com/KB/WPF/WPFDataGridExamples.aspx - WPF DataGrid Practical Examples
Dec 1, 2008 at 3:28 PM
Hi Thanks for answering. I see the problem. What is the recommend way to do it? The update is done regulary fromn a background thread.

If I should record the selection state - How to do it? Thanks for your help!
Dec 1, 2008 at 4:09 PM
Hmmm ... thats a tricky one.

If you have SelectionMode=FullRow the following will work:

private List<string> selectedPrimaryKeys = null;

private void Button_Click(object sender, RoutedEventArgs e)
{
    // record the primary key values for all selected rows
    selectedPrimaryKeys = new List<string>();
    foreach (DataRowView row in dataGrid.SelectedItems)
    {
        selectedPrimaryKeys.Add((string)row["CustomerID"]);
    }

    dataGrid.LoadingRow += new EventHandler<DataGridRowEventArgs>(dataGrid_LoadingRow);

    // refresh the table
    CustomerDataProvider provider = new CustomerDataProvider();
    this.DataContext = provider.GetCustomers();

    dataGrid.LoadingRow -= new EventHandler<DataGridRowEventArgs>(dataGrid_LoadingRow);
    selectedPrimaryKeys = null;

}

void dataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
    if (selectedPrimaryKeys == null)
        return;

    // find the DataTable row that this DataGrid row is assocaited with
    DataRowView rowView = e.Row.Item as DataRowView;

    // find its PK
    string pk = (string)rowView["CustomerID"];

    // determien whether it shoudl be selected
    if (selectedPrimaryKeys.Contains(pk))
    {
        e.Row.IsSelected = true;
    }
}

Basically, it iterates over the SelectedItems collection to record the primary keys of the selected items. We then refresh the data, as each new row is added to the DataGrid, we inspect its associated bound DataRowView to see whether it should be selected or not.

Hope that helps,
Regards,
Colin E.
--
http://wpfadventures.wordpress.com/ - my WPF blog
http://www.codeproject.com/KB/WPF/WPFDataGridExamples.aspx - WPF DataGrid Practical Examples