Hi Guys,
i am having problems with the focus in an root ListView when AutoCommit = true. Please see the attached sample + video. The ZIP also contains a database. The problem as far as i see is that i call Save() when the child list has changed, then, when making an change in an nested listview, the focus and so the current object is lost - see video! Is there an bug, is so, how can i prevent that i loose the focus in this situation?
thx
Noxe
Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.
Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.
Hi Noxe,
Thank you for the report. We need additional time to research this issue. We will get back to you once we have any results. Your patience is appreciated.
Thanks,
Michael.
Hi Noxe,
We have researched this issue and come to the conclusion that this behavior is by design. In the ListChanged event handlers of associated collections you are explicitly saving the owner object:
private void ArticlePurchases_ListChanged(object sender, ListChangedEventArgs e) { if (e.ListChangedType == ListChangedType.ItemAdded || e.ListChangedType == ListChangedType.ItemChanged || e.ListChangedType == ListChangedType.ItemDeleted) this.Save(); }
The Save method marks the object as modified even if there are no changes. This happens when the CommitChanges method is being executed and causes the object space reload. We recommend that you save the owner object from a controller instead.
Thanks,
Michael.
Hi Michael,
i dont really like the idea of handling this in an controller. the reason is that i also import objects, this happens without an view and so without an controller.
I understand that the object is saved and the collection source is reloaded, but 1) why does it only happen in this case where the change is made in nested-nested editable listview, and 2) why does it happen in general - since you have special code to keep the focus in the gridlisteditor, see gridView_FocusedRowChanged and prevFocusedRowHandle… ?
thx
Noxe
Hi Noxe,
Please pardon our delayed response. It took more than expected because we have to discuss it with the guys from the XPO team.
First, here is the short answer to your questions: our ListViewAutoCommitController with RefreshController simply do not support the scenario when right after committing objects it is necessary to save them again.
Thus, we cannot guarantee the proper operation of these controllers as well as dependent ones.
Second, here is a more detailed description of why you should not use your current code. When a collection is reloaded, your ArticlePurchases_ListChanged forces adding an object to the list of objects to save. It is done by the Save method that does not really commit data to the database (instead use the Session/ObjectSpace methods for that). This situation is incorrect, because the object itself did not change. Honestly, your code simply "confuses" our standard controllers and that is why we strongly recommend you avoid this.
Let me know if any further clarification on the subject is required.
Thanks,
Dennis
Hi Dennis,
thx for you rinvestigations. Lets me ask from another perspective. I want to set the ModifiedOn Date of the Master Object when something in an nested or nested-nested list object has been changed. currently i call save() because in my baseobject, in the onsaving method i set the modifiedon/by properties.
So what do you suggest? I need a global way like the current, but without the use of an controller - of course i can make an public method SetModifiedOn(), but i hoped that i can use my current logic without to place everywhere calls now to this method…?
thx
Noxe
Hi Dennis,
i tried now several things - i now completly removed my event handlers and the call to Save
private void ArticlePurchases_ListChanged(object sender, ListChangedEventArgs e)
{
if (e.ListChangedType == ListChangedType.ItemAdded || e.ListChangedType ==
ListChangedType.ItemChanged || e.ListChangedType == ListChangedType.ItemDeleted)
this.Save();
}
Then, i simply modified an setter of the nested object an modified an property of the master object -> this.Master.MyProperty = "test" -> this ALSO changes the focus in the listview! So it does not matter what i do, as far as i touch the master object, the focus in the root view is lost?
Hi Noxe,
Thank you for the additional information. We have reproduced this issue, but need additional time to research it. We will get back as soon as an answer is found.
Thanks,
Michael.
Hi Noxe,
>>>Then, i simply modified an setter of the nested object an modified an property of the master object -> this.Master.MyProperty = "test" -> this ALSO changes the focus in the listview!
When you change a property, the object is added to the "ObjectsToSave" list, just as when you call the Save method. That is why we recommend not to modify the object during the commitment. You can do this as I suggested in ticket Q393342.
>>>So it does not matter what i do, as far as i touch the master object, the focus in the root view is lost?
Yes, this behavior is expected. Besides the above workaround, we recommend that you disable the auto-commit behavior (remove your AutoCommitListViewController).
Thanks,
Michael.
Hi Michael,
your workaround works, but as you said in the other ticket "It seems that you are trying to use this event for its side effects, not for its designed purpose" -> probably yes.
Ok i want to get rid now of this event - here is what i need todo:
If a collection object is changed(on any level) - i need to set the modifiedon date of the master - without controller, on object level. Now it does also not work in the setter of a property, and you said:
"When you change a property, the object is added to the "ObjectsToSave" list, just as when you call the Save method. That is why we recommend not to modify the object during the commitment. "
I understand that the object is added to the list - but at this time we are not during commitment.
Disabling the auto-commit behavior is also not an option since this is the mode our endusers enter data in the list here.
So to come to an end, can you please post some example here you to solve this on object level in the setter of an property - without loosing the focus?
Hi Noxe,
I have discussed your scenario with our developers and we came to the conclusion that you cannot avoid losing focus if you use our ListViewAutoCommitController. Possibly, you could manage to avoid it if you implement the auto-commit functionality in a different manner, but we do not have a working solution at the moment.
Thanks,
Michael.
Hi Michael,
that answer would have helped from the beginning instead of suggesting different things.
thx anyway!
Hi Michael,
last reply on this topic. After 2 hours of debugging i personally think there is a small bug in the gridlisteditor in how it handles the previousfocused, i did it now with this controller. Basiscly i simply prevent the controller from subsequent calls to CommitChanges, because commitchanges is called here several times, and each time it is called during the previous commit. Easy - and works!
public class VDListViewAutoCommitController : ListViewAutoCommitController {
private bool _IsCommitChanges;
protected override void CommitChanges() {
if (this._IsCommitChanges)
return;
this._IsCommitChanges = true;
try {
base.CommitChanges();
}
finally {
this._IsCommitChanges = false;
}
}
}
Hi Noxe,
As far as I see it, the CommitChanges method is called from another CommitChanges method call only when ListViewAutoCommitController is used in an unusual scenario. This should not normally happen, and ListViewAutoCommitController is not designed for this scenario. Would you please elaborate more on "a small bug in the gridlisteditor in how it handles the previousfocused" and how to reproduce it when there is no nested CommitChanges method call?
Thanks,
Michael.
Hi Michael,
lets close this for now as i dont have enough free time to again do some debugging - as it works for me now, its ok for now. if i find some free time i will dig into this again!
thx
Noxe