-
Notifications
You must be signed in to change notification settings - Fork 324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
InvalidOperationException when deserializing layout #59
Comments
Hi I cannot verify your problem since you do not show your code
handler to handle the case in which you load a layout item that cannot be matched to a registered viewmodel/view. Your description sounds like this is what you are missing? If thats not the problem please either attach your code or try to explain your problem based on any of the demo projects in this repository, thanx |
Thanks for your response. We already have a handler: Unfortunately, I cannot show any more of the internal code than what I have already posted, |
The error message 'Collection was modified; enumeration operation may not execute.' does not appear to be a XML serializer specific message. It seems more likely that you are using a I would follow the suggestion on StackOverflow (change to This could of course also be a bug in AvalonDock but I'd be realy surprised if it was since nobody else has ever mentioned this specific exception... |
I was able to reproduce the exception only once using the TestApp demo project by randomly closing and reloading toolboxes. I also tried downgrading our AvalonDock version from 3.5.10 to 3.5.4.1 which solved the issue. |
Do you mean using version 3.5.4 solved your issue? Thats really strange because I don't think we've changed anything in particular about the layout serializer. Can you determine the version where it works for you and where it stops working (eg. version 3.5.4 works but version 3.5.5 dows not work)? |
Yes, 3.5.4 works fine for me but 3.5.5 does not. |
Thats interesting. The 2 versions are different by a small number of commits shown below in the commit history spanning from 2. May to 13. May. The actual number of commits relevant to us is smaller than whats shown in the history because we only need to look at commits that resulted in a change in the source/Components/Xceed.Wpf.AvalonDock/ library. Would you be able to setup a test project with the sources from 2. May (verify your problem does not exist) and move forward in the commit history (until 13 May) to see when your problem appears for the first time? This should enable us to find the actual commit that causes your problem and maybe even determine a fix for it :-) |
Question on the side: Does your exception also occur when you initialize the layout within the ui thread? I am only asking because I had this other issue with two other users and it turned out that one possible solution was to initialize the layout in the context of the ui thread (you may load the string within a background task but do the deserialization in the ui thread as shown in the link above). |
Hi, sorry for the late reply. initializing the layout inside or outside of the ui thread does not affect the issue. |
Hey, thanks for testing this but your result looks really impossible because you can see in the change log that the merge did not change anything in the source/Components/Xceed.Wpf.AvalonDock/ library. All that was changed was the Readme.md file, and some files in MLibTest which is a demo project (unless I am missing something here). So, the problem must at least either be one (or more) commit(s) before or after this commit, but not the linked commit (would you agree?) |
Yes, I fully agree, it does look strange, I'm just saying what results I came to. This is where the exception is thrown. I will check the commits again. |
The reference is relevant as it shows what I initially suggested. So, you could go ahead and replace the Foreach loops with the ToList() statements using for loops instead to test whether this results in a crash somewhere else - since that crash could indicate the real source of your problem. The code you are refering to is used in 81 places to recursively visit all Children of all Children in the Hierarchy of containers that can be configured in AvalonDock public static IEnumerable<ILayoutElement> Descendents( this ILayoutElement element )
{
var container = element as ILayoutContainer;
if( container != null )
{
foreach( var childElement in container.Children )
{
yield return childElement;
foreach( var childChildElement in childElement.Descendents() )
yield return childChildElement;
}
}
} The originating call seems to be coming from the DockingManager's. private void InternalSetActiveContent( object contentObject )
{
var layoutContent = Layout.Descendents().OfType<LayoutContent>().FirstOrDefault( lc => lc == contentObject || lc.Content == contentObject );
_insideInternalSetActiveContent = true;
Layout.ActiveContent = layoutContent;
_insideInternalSetActiveContent = false;
} So, this makes me wonder, if the controls that you use within the AvalonDock containers are:
this may even be initiated through a bound viewmodel. So, another way of isolating this problem could be to test whether deactivating code attached to OnLoadEvents of each control (and other such events) would lead to an absence of the error - if yes - we would know at last how the problem was triggered but not why, yet... Either way, it should be possible to isolate the problem either in the test appliactions in this repository (by adjusting the test application such that your problem is visible) or adjusting a test version of you own application such that the problem is no longer verifyable... The result should be that we find:
I take it the layout is not the problem as you were able to check with the test apps? Maybe its time to take a hard look at your app then? |
@Dirkster99 I also get an error with the MFLibTest application. I used the application to find out why the AutoHide not working. I get the error in the DockingManager Class in the method DockingManager_Loaded And I also get the error in the Extension method in my Application when I load different Layouts at runtime.I have only Tool-Windows in my Application. So what I do actually is, before I load a new Layout I set by all the Toolwindows the property isvisible = false. I hope this helps to find the error in AvalonDock. It must be a race condition when AvalonDock add and removes anchorables. |
OK, I can verify the exception with the Layout from @Martin5630 thanks for that - I can now look deeper into it :-) The source of the problem in the layout from @Martin5630 seems to be the
More precisly, I can remove the A possible fix for the exception from @Martin5630 seems to be to finish the query before adding the new FloatingWindowControls in the List<LayoutFloatingWindow> items = new List<LayoutFloatingWindow>(Layout.FloatingWindows.Where(fw => !_fwList.Any(fwc => fwc.Model == fw)));
foreach ( var fw in items)
_fwList.Add( CreateUIElementForModel( fw ) as LayoutFloatingWindowControl ); I have to think about this - it looks like there are too many linq queries based on events and events of events that will eventually create a race condition as we see here, so I am not sure if the above is really a solution or just a hack :-( |
Hi @dazawa and @Martin5630 I have created a fix candidate for the deserializing issues discussed here: This candidate is in a seperate branch to make sure it does fix the issue and breaks nothing else - would you guys please download, compile and test the branch to see if this clears your issues that you mentioned?
It would also be good if you could do some general testing to amke sure nothing new creps up:
Branch for testing is here: EnumInvalidOperationException |
Hi @Dirkster99 Thanks for the effort! I will test as soon as I get back, which will be in a couple of days and will post an update here. |
This issue should be fixed with version 3.6.1 (just released it now) |
Hey @Dirkster99 |
That's really strange, I expected this to resolved now :-( can you please post the current stack trace one more time? - at least some line numbers should be different now … I am really at a lost end since I cannot debug your problem so I am not able to find a fix - do you have any suggestion towards a fix? |
Here's the full StackTrace
|
OK, since this nut seems to be a little harder to crack, please do also think about additional evidence like screenshot of the case in VS or (even better) a separate test client showing the problem with a certain workflow. |
@jacobavenkraft Thanks for the useful feedback - I've implemented a fix as you suggested above and hope this will finally fix this issue. I am going to do another release soon ... |
Hi,
when attempting to deserialize a saved layout from XML, I get the following exception:
It seems to be reproducable by moving or removing a LayoutAnchrablePane that is contained within the serialized layout and then deserializing the layout.
Here is the deserialization code:
var serializer = new XmlLayoutSerializer(dockingManager); serializer.LayoutSerializationCallback += SerializerLayoutSerializationCallback; [...] using (var stream = new StreamReader(defaultLayout)) { serializer.Deserialize(stream); }
(The exception is thrown somewhere inside
serializer.Deserialize(stream);
)StackTrace:
I added the layout I am trying to deserialize:
layout.zip
Kind Regards,
David
The text was updated successfully, but these errors were encountered: