6

I want to do something that I thought would be very simple. I want to bind a generated Entity Framework EntityCollection to a WPF DataGrid. I also want this grid to be sortable.

I have tried all kinds of things to make this happen, including using a CollectionViewSource. However, nothing seems to work. Using a normal CollectionViewSource around the EntityCollection gives me:

'System.Windows.Data.BindingListCollectionView' view does not support sorting.

Ok...strange. I would have thought this would work. Next on the CollectionViewSource, I try setting:

 CollectionViewType="ListCollectionView"

Great, sorting now works. But wait, I can't add or remove entities using the grid now, presumably because ListCollectionView doesn't support this with an entity framework context.

So, I guess I need to capture events coming out of the datagrid in order to add or remove entities manually from my context. Now I can't find an event to capture to detect an add...!

Why is this so hard? This should be the standard "demo" case that Microsoft should have designed around.

Any ideas?

Mike Gates
  • 1,874
  • 3
  • 21
  • 40

2 Answers2

2

BindingListCollectionView is not directly the problem. See 'System.Windows.Data.BindingListCollectionView' view does not support sorting on Microsoft Connect for details why it does not support sorting.

On the other hand ListCollectionView supports sorting obviously using a different technique.

I have also tried the following code and it worked beautifully. I have basically implemented your XAML from the other post in code.

 DatabaseContext.ObjectStateManager.ObjectStateManagerChanged += (o, args) => Debug.WriteLine(args.Element.ToString());

 var collectionViewSource = new CollectionViewSource();
 ((ISupportInitialize)collectionViewSource).BeginInit();
 collectionViewSource.CollectionViewType = typeof (ListCollectionView);
 collectionViewSource.Source = ((IListSource) DatabaseContext.Survey).GetList();
 collectionViewSource.SortDescriptions.Add(new SortDescription {PropertyName = "Name"});
 ((ISupportInitialize)collectionViewSource).EndInit();

 var editableCollectionView = (IEditableCollectionView)collectionViewSource.View;
 var survey = editableCollectionView.AddNew();

 // Before this point ObjectStateManager event has occurred and Debug Output is written to.

 editableCollectionView.CommitNew();
 DatabaseContext.SaveChanges(); // THIS WORKS TOO!

My DatabaseContext.Survey is an ObjectQuery<Survey>. Are you showing an ObjectQuery or a Linq-to-EF query? The former obviously works for me. The latter is where I see a problem. That is not supposed to work.

Community
  • 1
  • 1
wpfwannabe
  • 14,587
  • 16
  • 78
  • 129
  • Yes, the ListCollectionView does in fact work. I was confused because adding to this via databinding was not adding to what I thought were the "root" collections which I was binding to (myContext.Employees for example). I was mistaken thinking these were mutable collections when in fact they were not, and the only way to get at my "new" entities was throught the ObjectStateManager. – Mike Gates Apr 27 '10 at 13:13
  • This indeed seems to work great. It is sad that the default EF RAD stuff doesn't take care of this of the box. That said, remember that if you are using ListCollectionView CollectionViewType with EF4, you'll have to set AutoGenerateColumns to False to avoid getting the EntityState and EntityKey columns. – Spooles Apr 10 '12 at 22:59
0

It seems like, the View just doesn't get notified, when chages occur. So, I just do

myCollectionViewSource.View.Refresh(); //refresh CollectionViewSource of CollectionViewType="ListCollectionView"

after add/remove of list items.

But then the whole state gets refreshed (e.g. you have to reset preselected sorting again). You need to check, if this fits your needs.

OneWorld
  • 17,512
  • 21
  • 86
  • 136