-
-
Notifications
You must be signed in to change notification settings - Fork 404
Description
Describe the bug
When cloning an object graph that contains children, the edit level of the children is not correctly preserved.
Example scenario is Invoice with Cost line items. There is a BindingSource for the invoice and one for the child cost list.
Creating a clone and showing a new form with that cloned object triggers an EditLevelMismatch exception.
Version and Platform
CSLA version: 9.1.0
OS: Windows
Platform: WinForms
Code that Fails
I created a simple demo project to showcase the issue here: https://github.com/xal1983/CslaEditLevelMismatch/blob/master/EditLevelMismatch/Form1.cs
But the gist of it is, the child cost and it's field manager have an EditLevel = 1 at the time of cloning the invoice.
The cloned cost however ends up with EditLevel = 0 but it's FieldManager has an EditLevel = 1.
When setting the binding source, the binding source will automaticall call IEditableObject.BeginEdit() on the cost and Csla will raise the exception because the FieldManager and the Cost's EditLevels do not match.
Stack Trace or Exception Detail
at Csla.Core.FieldManager.FieldDataManager.Csla.Core.IUndoableObject.CopyState(Int32 parentEditLevel, Boolean parentBindingEdit) in //Source/Csla/Core/FieldManager/FieldDataManager.cs:line 512
at Csla.Core.UndoableBase.CopyState(Int32 parentEditLevel) in //Source/Csla/Core/UndoableBase.cs:line 167
at Csla.Core.BusinessBase.System.ComponentModel.IEditableObject.BeginEdit() in /_/Source/Csla/Core/BusinessBase.cs:line 778
at System.Windows.Forms.CurrencyManager.OnCurrentChanged(EventArgs e)
at System.Windows.Forms.CurrencyManager.ChangeRecordState(Int32 newPosition, Boolean validating, Boolean endCurrentEdit, Boolean firePositionChange, Boolean pullData)
at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
at System.Windows.Forms.BindingSource.OnListChanged(ListChangedEventArgs e)
at System.Windows.Forms.BindingSource.ResetBindings(Boolean metadataChanged)
at System.Windows.Forms.BindingSource.SetList(IList list, Boolean metaDataChanged, Boolean applySortAndFilter)
at System.Windows.Forms.BindingSource.ResetList()
at System.Windows.Forms.BindingSource.ParentCurrencyManager_MetaDataChanged(Object sender, EventArgs e)
at System.Windows.Forms.CurrencyManager.OnMetaDataChanged(EventArgs e)
at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e)
at System.Windows.Forms.BindingSource.OnListChanged(ListChangedEventArgs e)
at System.Windows.Forms.BindingSource.ResetBindings(Boolean metadataChanged)
at System.Windows.Forms.BindingSource.SetList(IList list, Boolean metaDataChanged, Boolean applySortAndFilter)
at System.Windows.Forms.BindingSource.ResetList()
at System.Windows.Forms.BindingSource.set_DataSource(Object value)
at EditLevelMismatch.Form1.SetDataSource(Invoice i) in E:\Devel\Tests\EditLevelMismatch\EditLevelMismatch\Form1.cs:line 27
at EditLevelMismatch.Form1.button1_Click(Object sender, EventArgs e) in E:\Devel\Tests\EditLevelMismatch\EditLevelMismatch\Form1.cs:line 46
Additional context
So, you may suggest "Call EndEdit or CancelEdit before cloning". however, this is precisely what I can't do. The use case is:
-User sees a list of invoices with the editor
-User start editing an invoice
-User needs to look up information from another invoice while editing the invoice
-At this point the app creates a clone of the in progress edit of the invoice and shows a popup with just the editor for this invoice, any edits being made so far need to be preserved, but the user needs to be able to cancel if they want to discard changes.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status