views:

497

answers:

2

I am working on an MVVM-based WPF app that uses the DataGrid. The grid is data-bound to an ObservableCollection (the Widget list). The user needs to be able to insert a Widget into the list below the currently-selected Widget, to delete a selected Widget, and to reorder the Widgets on the grid. I'll implement the reordering through dragging and dropping.

Before I dig into this, I want to get a reality check on my approach. Here is what I am planning to do: The Widget class will have an Index property that will be used to order the Widget list. Additions, deletions, and reordering will be done by manipulating this Index property, and sorting will be done on the Widget list, rather than through a CollectionView.

Before the DataContext is set, the Widget list will be sorted on the Index property. When a user adds a Widget, the Index property will be incremented by 1 for each Widget below the selected item on the grid, and the new Widget will be given the index number opened up by the renumbering. The Widget list will resorted, and the bindings will be refreshed.

When a user deletes a Widget, the Widget will be removed from the list, and the Index property of items on the grid below the deleted item will be decremented by 1. The Widget list will be resorted, and the bindings refreshed, as above. Reordering will be done as a combination delete-and-insert.

Here is my question: Is this a reasonable strategy for implementing inderting, deleting, and reordering? Is there a better way to go about it? Any good articles or blog posts on the subject? I've looked, but I'm not coming up with anything on-point.

Thanks for your help.

A: 

Improving sorting performance: http://blogs.msdn.com/jgoldb/archive/2008/10/30/improving-microsoft-datagrid-sorting-performance-part-3.aspx

Trainee4Life
Sory, it doesn't really address the question that was asked. I am looking for feedback on the approach, not datagrid sorting tips.
David Veeneman
A: 

I've got this problem figured out. I do need the Index property, but I don't need to sort the ObservableCollection. I create an interface, IIndexedObject, with one property, Index. I implement that interface on any object that needs to be indexed, and in my database table, I add an Index column.

When I load into my object model, I sort the database table on the Index property. That ensures that the list is loaded in the same order as in the last run. I add objects using the blank row provided at the bottom of the DataGrid. It gives them an index of 0. I delete objects using a Delete button bound to an ICommand in the view model.

My view model subscribes to the CollectionChanged property of any ObservableCollection that contains IIndexedObjects. When the event fires, the view model passes the collection to a ReIndexCollection service method, which takes an IIndexedObject. The method re-indexes the collection, based on its current order, by simply iterating the collection, assigning an incremental integer value to each element's Index property. When I persist the collection back to the database, the Index value gets saved, to ensure that the collection is loaded in the same order on the next run.

Since the only sorting that is needed is done at the database load, there is no need to sort the ObservableCollection. When I move items on the DataGrid, it will take care of re-ordering the collection at that time. All I have to do is re-index the collection, so that its order will be persisted back to the database.

All-in-all, it's much easier than I had expected. One of the reasons I like WPF and MVVM.

David Veeneman