Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 91519

Exception while trying to RaiseChild during Container.LayoutChanged on Android.

$
0
0

I am working on a video layout manager for a conference app. The following code is an excerpt for a Layout manager for a custom renderer. It works fine on iOS, but on Android it throws an System.InvalidOperationException: Cannot change ObservableCollection during a CollectionChanged event. when Container.RaiseChild (localVideoControl); is run after calling AddToContainer().

public class FormsLayoutManager : BaseLayoutManager
{
    public AbsoluteLayout Container { get; private set; }

    private bool InLayout = false;

    public FormsLayoutManager (AbsoluteLayout container, LayoutPreset preset)
        : base (preset)
    {
        Container = container;

        Container.LayoutChanged += (object sender, EventArgs e) => {
            if (!InLayout) {
                Device.BeginInvokeOnMainThread (DoLayout);
            }
        };
    }

    public override void AddToContainer (object control)
    {
        Container.Children.Add ((View)control);
    }

    public override void RemoveFromContainer (object control)
    {
        Container.Children.Remove ((View)control);
    }

    public override void ApplyLayout ()
    {
        InLayout = true;
        try {
            var localVideoControl = (View)GetLocalVideoControl ();
            var remoteVideoControls = GetRemoteVideoControls ();

            var layoutWidth = (int)Container.Width;
            var layoutHeight = (int)Container.Height;

            // Get the new layout.
            var layout = GetLayout (layoutWidth, layoutHeight, remoteVideoControls.Length);

            // Apply the local video frame.
            if (localVideoControl != null) {
                var localFrame = layout.LocalFrame;
                AbsoluteLayout.SetLayoutBounds (localVideoControl, new Rectangle (localFrame.X, localFrame.Y, localFrame.Width, localFrame.Height));

                if (Mode == LayoutMode.FloatLocal) {
                    Container.RaiseChild (localVideoControl);   //<--- System.InvalidOperationException: Cannot change ObservableCollection during a CollectionChanged event.
                }
            }

            // Apply the remote video frames.
            var remoteFrames = layout.RemoteFrames;
            for (int i = 0; i < remoteFrames.Length; i++) {
                var remoteFrame = remoteFrames [i];
                var remoteVideoControl = (View)remoteVideoControls [i];
                AbsoluteLayout.SetLayoutBounds (remoteVideoControl, new Rectangle (remoteFrame.X, remoteFrame.Y, remoteFrame.Width, remoteFrame.Height));

                if (Mode == LayoutMode.FloatRemote) {
                    Container.RaiseChild (remoteVideoControl);
                }
            }
            Container.ForceLayout ();
        } finally {
            InLayout = false;
        }
    }
}

Viewing all articles
Browse latest Browse all 91519

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>