DataGrid SelectedItem lost after bound Observable<T> collection cleared and repopulated

Nov 14, 2008 at 4:17 PM
To start,
I would like to thank you for the development effort that produced WPF DataGrid.

Here I would like to present a scenario that I cannot seem to figure out:

I created a class called StockModel has a property of type ObservableCollection<StockQuotes> which is bound to the DataGrid.  

<ObjectDataProvider x:Key="StockDataSource"
       ObjectType="{x:Type local:StockModel}"/>

 <dg:DataGrid x:Name="grdStocks" Grid.Column="0" Grid.Row="1" ItemsSource="{Binding Source={StaticResource StockDataSource},Path=StockList}" AutoGenerateColumns="False" Margin="2"
                     GridLinesVisibility="Horizontal"
                     RowHeaderWidth="0"
                     SelectionMode="Extended"
                     RowEditEnding="DataGrid_RowEditEnding" SelectionUnit="FullRow"
                     RowBackground="White"
                     Background="Transparent"
                     AlternatingRowBackground="LightGray"
                     AlternationCount="2"
                     IsSynchronizedWithCurrentItem="True"
                     CellStyle="{StaticResource defaultCellStyle}"
                     RowStyle="{StaticResource defaultRowStyle}"
                     CanUserAddRows="False">

StockModel class implements INotifyPropertyChanged.

StockQuotes is the Linq-to-SQL class that I created.

To Delete I remove the StockQuote item from database using DataContext of the StockQuotes Linq-to-SQL class.
Then clear the ObservableCollection<StockQuotes> and repopulate it with data.

The Grid is updated, but looses selection.

There are two problems that I have.

1. Consolidation of remove/add operations.
There sholud be one place where I can remove item from the grid and database. 
Currently I either have to call EditableCollection's Remove(), to remove item from the grid and then call DataContext of Linq-to-SQL class to perform database operation.
In this case Selection is not lost, but I have to make two calls.

To Add item, for lack of any other way, I could add directly to the Grid's underlying model and then call DataContext of Linq-to-SQL class to perform database operation.
In this case Selection is kept at the previously selected row. Note: I don't use in-grid new item add feature and have my own dialog instead.

In any case I would be forced to make two calls one to the perform an operation on the grid
and one to perform an operation on the database. To avoid this duplication, I perform operation on the database and then clear collection and repopulate it.
This brings me to the second problem.

2. How do I keep the selection on the first row of the Grid.
Something like grdStocks.Items[0].IsSelected = True;
So far I was not able to figure it out.

All help would be greatly appreciated.

Regards,

Boris
Nov 14, 2008 at 4:46 PM
Hi Boris,

To set the index of the selected item just use the Datagrid.SelectedItem property.

Regarding remove/add operations, if the DataGrid is bound to an ObservableCollection, you should simply be able to add ./ remove items and the DataGrid will update accordingly. I'm afraid I am no expert with Linq-to-SQL, however I have created a few examples with DataSets:

http://www.codeproject.com/KB/WPF/WPFDataGridExamples.aspx

Maybe I should work out how to do the same with Linq-to-SQL and extends these examples?

Colin E.


Nov 14, 2008 at 8:05 PM
Colin,

I can show how Remove/Add performed on the DataGrid model run into heaps of problems when trying to reconsile with DataContext of a Linq-to-SQL.
 
First lets forget for a second that there is no decent way to add item using EditableCollection. So to make it work I have to do something like this:
private StockModel model;
 System.Windows.Data.ObjectDataProvider dp = (System.Windows.Data.ObjectDataProvider)FindResource("StockDataSource");
 model = (StockModel)dp.Data; 
model contains the following:  
private ObservableCollection<StockQuotes> stockList = new ObservableCollection<StockQuotes>();
        public ObservableCollection<StockQuotes> StockList
        {
            get { return stockList; }
        }

So to add I can do:     model.Add(item);

Now ObservableCollection<StockQuotes> will notify the DataGrid of changes made to the collection.

However when I try to do a subsequent delete from the database, DataContext doesn't know about this item and will throw an Exception.

The challenge as I see it would be keeping the collection and database in sync.


Second problem is adding of the item to the DataGrid. How can I add new item to the collection of items?

Regards,

Boris