I have an application where we allow the user to save custom layouts for a grid. This is done in a behavior. The user can have a separate layout for different products, this is handled with an attached property on the behavior when the user change the selected product and make changes to the grid layout. When the application loads, the layout, if any will be loaded. Everything works find up to this point, the layout is loaded and the grid is still enabled to add further rows. The problem is when the selected product is changed, and the layout reloaded for the product. The correct layout is loaded, but the ability to add rows seems to disappear or being reset, when looking into the visual tree the AllowAddNew flag is still true, nothing else seems to have changed. I attached a small sample project that illustrates the problem.
I will appreciate if someone could have a look at the sample project and advise on a way around this or is this a known issue?
Regards
4024.WpfApp1.zip
Thank you, that works.
Hi Adele,
The issue stems from the ListCollectionView actually. When you change the Product value this causes the ListCollectionView's CanAddNew property to become false because there is currently an edit transaction occurring. In the middle of this edit transaction, LoadCustomizations() is being called and during this process the AddNewRecord get's removed because the grid thinks ListCollectionView doesn't allow new items (because CanAddNew is false). To resolve this you need to end the edit transaction before calling LoadCustomizations.
In your behavior change the LoadLayout method to look like this:
protected void LoadLayout(string fileName) { Application.Current.Dispatcher.BeginInvoke(new Action(() => { try { var path = System.IO.Path.Combine(LayoutPath, fileName); if (System.IO.File.Exists(path)) using (var file = System.IO.File.OpenRead(path)) { AssociatedObject.ExecuteCommand(DataPresenterCommands.EndEditModeAndCommitRecord); AssociatedObject.LoadCustomizations(file); } } catch (Exception ex) { Debug.WriteLine("Error loading layout {0}", ex.Message); } })); }
The BeginInvoke is required because you can't end edit mode in the grid in the middle of the Product property changed event which the behavior is currently doing. This BeginInvoke allows the grid to react properly when you execute the EndEditModeAndCommitRecord command.