/// <summary>
        /// Manages the children of a React view.
        /// </summary>
        /// <param name="tag">The tag of the view to manager.</param>
        /// <param name="indexesToRemove">Child indices to remove.</param>
        /// <param name="viewsToAdd">Views to add.</param>
        /// <param name="tagsToDelete">Tags to delete.</param>
        public void ManageChildren(int tag, int[] indexesToRemove, ViewAtIndex[] viewsToAdd, int[] tagsToDelete)
        {
            var viewManager = default(IViewManager);

            if (!_tagsToViewManagers.TryGetValue(tag, out viewManager))
            {
                throw new InvalidOperationException(
                          Invariant($"Trying to manage children with tag '{tag}' which doesn't exist."));
            }

            var ViewParentManager = (IViewParentManager)viewManager;
            var viewToManage      = _tagsToViews[tag];

            var lastIndexToRemove = ViewParentManager.GetChildCount(viewToManage);

            if (indexesToRemove != null)
            {
                for (var i = indexesToRemove.Length - 1; i >= 0; --i)
                {
                    var indexToRemove = indexesToRemove[i];
                    if (indexToRemove < 0)
                    {
                        throw new InvalidOperationException(
                                  Invariant($"Trying to remove a negative index '{indexToRemove}' on view tag '{tag}'."));
                    }

                    if (indexToRemove >= ViewParentManager.GetChildCount(viewToManage))
                    {
                        throw new InvalidOperationException(
                                  Invariant($"Trying to remove a view index '{indexToRemove}' greater than the child could for view tag '{tag}'."));
                    }

                    if (indexToRemove >= lastIndexToRemove)
                    {
                        throw new InvalidOperationException(
                                  Invariant($"Trying to remove an out of order index '{indexToRemove}' (last index was '{lastIndexToRemove}') for view tag '{tag}'."));
                    }

                    var viewToRemove = ViewParentManager.GetChildAt(viewToManage, indexToRemove) as Widget;
                    if (viewToRemove != null &&
                        _layoutAnimator.ShouldAnimateLayout(viewToRemove) &&     //TODO: LayoutAnimation will be merged later .. BOY.YANG
                        tagsToDelete != null && tagsToDelete.Contains(viewToRemove.GetTag()))
                    {
                        // The view will be removed and dropped by the 'delete'
                        // layout animation instead, so do nothing.
                    }
                    else
                    {
                        ViewParentManager.RemoveChildAt(viewToManage, indexToRemove);
                    }

                    lastIndexToRemove = indexToRemove;
                }
            }

            if (viewsToAdd != null)
            {
                for (var i = 0; i < viewsToAdd.Length; ++i)
                {
                    var viewAtIndex = viewsToAdd[i];
                    var viewToAdd   = default(Widget);
                    if (!_tagsToViews.TryGetValue(viewAtIndex.Tag, out viewToAdd))
                    {
                        throw new InvalidOperationException(
                                  Invariant($"Trying to add unknown view tag '{viewAtIndex.Tag}'."));
                    }

                    //Log.Info(ReactConstants.Tag, "## ManageChildren ## viewToManage:" + viewToManage + " viewToAdd:" + viewToAdd
                    //    + " Index:"+ viewAtIndex.Index);
                    ViewParentManager.AddView(viewToManage, viewToAdd, viewAtIndex.Index);
                }
            }

            if (tagsToDelete != null)
            {
                for (var i = 0; i < tagsToDelete.Length; ++i)
                {
                    var tagToDelete   = tagsToDelete[i];
                    var viewToDestroy = default(Widget);
                    if (!_tagsToViews.TryGetValue(tagToDelete, out viewToDestroy))
                    {
                        throw new InvalidOperationException(
                                  Invariant($"Trying to destroy unknown view tag '{tagToDelete}'."));
                    }

                    var elementToDestroy = viewToDestroy as Widget;
                    if (elementToDestroy != null &&
                        _layoutAnimator.ShouldAnimateLayout(elementToDestroy))   //TODO: LayoutAnimation will be merged later .. BOY.YANG
                    {
                        _layoutAnimator.DeleteView(elementToDestroy, () =>
                        {
                            if (ViewParentManager.TryRemoveView(viewToManage, viewToDestroy))
                            {
                                DropView(viewToDestroy);
                            }
                        });
                    }
                    else
                    {
                        DropView(viewToDestroy);
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Manages the children of a React view.
        /// </summary>
        /// <param name="tag">The tag of the view to manager.</param>
        /// <param name="indexesToRemove">Child indices to remove.</param>
        /// <param name="viewsToAdd">Views to add.</param>
        /// <param name="tagsToDelete">Tags to delete.</param>
        public void ManageChildren(int tag, int[] indexesToRemove, ViewAtIndex[] viewsToAdd, int[] tagsToDelete)
        {
            var viewManager = default(IViewManager);

            if (!_tagsToViewManagers.TryGetValue(tag, out viewManager))
            {
                throw new InvalidOperationException(
                          Invariant($"Trying to manage children with tag '{tag}' which doesn't exist."));
            }

            var viewParentManager = (IViewParentManager)viewManager;
            var viewToManage      = _tagsToViews[tag];

            var lastIndexToRemove = viewParentManager.GetChildCount(viewToManage);

            if (indexesToRemove != null)
            {
                for (var i = indexesToRemove.Length - 1; i >= 0; --i)
                {
                    var indexToRemove = indexesToRemove[i];
                    if (indexToRemove < 0)
                    {
                        throw new InvalidOperationException(
                                  Invariant($"Trying to remove a negative index '{indexToRemove}' on view tag '{tag}'."));
                    }

                    if (indexToRemove >= viewParentManager.GetChildCount(viewToManage))
                    {
                        throw new InvalidOperationException(
                                  Invariant($"Trying to remove a view index '{indexToRemove}' greater than the child could for view tag '{tag}'."));
                    }

                    if (indexToRemove >= lastIndexToRemove)
                    {
                        throw new InvalidOperationException(
                                  Invariant($"Trying to remove an out of order index '{indexToRemove}' (last index was '{lastIndexToRemove}') for view tag '{tag}'."));
                    }

                    var viewToRemove = viewParentManager.GetChildAt(viewToManage, indexToRemove) as FrameworkElement;
                    if (viewToRemove != null &&
                        _layoutAnimator.ShouldAnimateLayout(viewToRemove) &&
                        tagsToDelete.Contains(viewToRemove.GetTag()))
                    {
                        // The view will be removed and dropped by the 'delete'
                        // layout animation instead, so do nothing.
                    }
                    else
                    {
                        viewParentManager.RemoveChildAt(viewToManage, indexToRemove);
                    }

                    lastIndexToRemove = indexToRemove;
                }
            }

            if (viewsToAdd != null)
            {
                for (var i = 0; i < viewsToAdd.Length; ++i)
                {
                    var viewAtIndex = viewsToAdd[i];
                    var viewToAdd   = default(DependencyObject);
                    if (!_tagsToViews.TryGetValue(viewAtIndex.Tag, out viewToAdd))
                    {
                        throw new InvalidOperationException(
                                  Invariant($"Trying to add unknown view tag '{viewAtIndex.Tag}'."));
                    }

                    viewParentManager.AddView(viewToManage, viewToAdd, viewAtIndex.Index);
                }
            }

            if (tagsToDelete != null)
            {
                for (var i = 0; i < tagsToDelete.Length; ++i)
                {
                    var tagToDelete   = tagsToDelete[i];
                    var viewToDestroy = default(DependencyObject);
                    if (!_tagsToViews.TryGetValue(tagToDelete, out viewToDestroy))
                    {
                        throw new InvalidOperationException(
                                  Invariant($"Trying to destroy unknown view tag '{tagToDelete}'."));
                    }

                    var elementToDestroy = viewToDestroy as FrameworkElement;
                    if (elementToDestroy != null &&
                        _layoutAnimator.ShouldAnimateLayout(elementToDestroy))
                    {
                        var viewToDestroyManager = ResolveViewManager(tagToDelete);
                        _layoutAnimator.DeleteView(viewToDestroyManager, elementToDestroy, () =>
                        {
                            if (viewParentManager.TryRemoveView(viewToManage, viewToDestroy))
                            {
                                DropView(viewToDestroy);
                            }
                        });
                    }
                    else
                    {
                        DropView(viewToDestroy);
                    }
                }
            }

            _deletedTagsBatchReporter.Send();
        }