Open KPixel opened 4 years ago
Attached reproduction sample:
The exception:
Unable to cast COM object of type 'System.Collections.Specialized.NotifyCollectionChangedEventHandler' to class type 'System.Collections.Specialized.NotifyCollectionChangedEventHandler'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
Description
In the implementation of multi-window (for UWP) in #2432, all layout changes are batched in a static list:
https://github.com/xamarin/Xamarin.Forms/blob/52592fac6158c9f3abb9118c2ceca6c348e21c98/Xamarin.Forms.Core/Layout.cs#L62
This fails with multiple windows because they each have their own dispatcher.
Steps to Reproduce
The Control Gallery already has a multi-window sample, so we will add some extra code to repro this bug:
Run the Control Gallery app and click on the "Open Secondary Window" button twice.
Click on the new button.
Expected Behavior
The font size of this button should increase in all windows.
Actual Behavior
The app crashes.
Basic Information
Solution
My solution is to batch the layouts changes per dispatcher.
s_resolutionList
with:You can also delete the method GetElementDepth() which doesn't seem to be needed.
Note that I use a
HashSet
of layouts to avoid scheduling the same layout multiple times. I've noticed that this can happen. Small perf detail: It would be better if theIDispatcher
implementations were IEquatable<>. This will ensure that the dictionary only contains one dispatcher per window to minimize the number of batches. But most of the time, this should not matter. Also, see this comment...By the way, I experimented with this solution after fixing the bugs in #11705 and #11880. So, my local X.F doesn't exactly match with 4.8.0.1269, and this solution assumes that those bugs are fixed.