Ejemplo n.º 1
0
        /// <summary>
        /// Rescues a Value if it has Valid References
        /// </summary>
        /// <param name="valueDeleted">It's the UniqueID of the IStateObject being deleted</param>
        /// <param name="branchUniqueID">It's the Root object that started the Deletion process.</param>
        /// <returns>True if the Value had valid references and it was rescued from deletion.</returns>
        internal bool RescueValue(string objToRemoveUniqueID, string branchUniqueID = null, bool allowUnAttachedReferences = true, bool isDispose = false, IFormBaseViewModel formBaseViewModel = null, HashSet <string> _objectsToBeValidatedAfterDisposeHashSet = null)
        {
            if (branchUniqueID == null)
            {
                branchUniqueID = objToRemoveUniqueID;
            }

            var referencesTable = GetObjectReferencesTable(objToRemoveUniqueID);

            if (referencesTable != null)
            {
                referencesTable.ValidateReferences(branchDeleted: branchUniqueID, validateUnAttached: !allowUnAttachedReferences);
                //If the object to be removed is a ListItem AND the referencesTable's count is major than zero,
                //then we have a special block for handling this situation.
                if (UniqueIDGenerator.IsListItem(objToRemoveUniqueID) && referencesTable.Count > 0)
                {
                    //If the referenced object is IViewModel, or IDisposableDependencyControl,
                    //we should never rescue them.
                    if (isDispose && referencesTable.IsReferencedObjectAnIDisposableDependencyControl)
                    {
                        return(false);
                    }
                    //If there are some valid references, we should rescue it.
                    else if (HasValidReferencesForListItem(referencesTable, objToRemoveUniqueID, _objectsToBeValidatedAfterDisposeHashSet))
                    {
                        RescuedValueUniqueIdHashSet.Add(objToRemoveUniqueID);
                        return(true);
                    }
                    //otherwise, we shouldn't resue it
                    else
                    {
                        return(false);
                    }
                }
                else if (referencesTable.Count > 0)//No references
                {
                    bool res = TransferValueToReference(branchUniqueID, referencesTable, isDispose: isDispose, formBaseViewModel: formBaseViewModel);
                    if (res)
                    {
                        RescuedValueUniqueIdHashSet.Add(objToRemoveUniqueID);
                    }
                    return(res);
                }
            }
            //Given this kind of uniqueID: x#y#KIXYZ
            // We have to validate if KIXYZ has been rescued previously,
            // if this KIXYZ has been rescued, we should skip this uniqueID
            var accessPathIndex = objToRemoveUniqueID.LastIndexOf(UniqueIDGenerator.UniqueIdSeparator);

            if (accessPathIndex > 0)
            {
                var ancestorUID = objToRemoveUniqueID.Substring(accessPathIndex + 1);
                var canRescue   = RescuedValueUniqueIdHashSet.Contains(ancestorUID) && !_stateManager.IsInElementsToRemove(ancestorUID);
                if (UniqueIDGenerator.IsListItem(ancestorUID) && canRescue)
                {
                    return(true);
                }
            }
            return(false);
        }
Ejemplo n.º 2
0
        private bool TransferValueToReference(string branchRemoved, ReferencesTable referencesTable, IStateObject elementToAdoptObj = null, bool isDispose = false, IFormBaseViewModel formBaseViewModel = null)
        {
            if (isDispose && referencesTable.IsReferencedObjectAnIDisposableDependencyControl)
            {
                return(false);
            }
            //If the elementToAdopt was not sent as a parameter let's calculate it.
            if (elementToAdoptObj == null)
            {
                elementToAdoptObj = referencesTable.ReferencedObject;
            }
            string oldParentUniqueID = elementToAdoptObj.UniqueID;

            //Entire windows won't be preserved.
            if (elementToAdoptObj is IViewModel)
            {
                return(false);
            }
            //Let's get the reference candidate for the adoption.
            var reference = GetReferenceValidForAdoption(referencesTable, false);

            if (reference == null)
            {
                return(false);
            }
            var candidate = CalculateCandidateForAdoption(reference);

            //The cadidates parent was already removed...Ciao
            if (candidate == null)
            {
                return(false);
            }
            bool doNotRegisterIDSwitch = true;

            if (formBaseViewModel == null)
            {
                formBaseViewModel = ViewManager.Instance.GetTopLevelObject(elementToAdoptObj) as IFormBaseViewModel;
            }
            if (formBaseViewModel != null)
            {
                doNotRegisterIDSwitch = formBaseViewModel.IsDisposing;
            }

            if (!(elementToAdoptObj is IDisposableDependencyControl) || (!isDispose && !doNotRegisterIDSwitch))
            {
                //The element won't belong to the parent anymore.
                IStateObject elementsToBeAdopted = _stateManager.DettachObject(elementToAdoptObj, !doNotRegisterIDSwitch);
                //We need to promote the object and attach it to the first candidate.
                AdoptionInformation.StaticAdopt(candidate, elementsToBeAdopted);
                ////Let's update all the references
                UpdateReferencesTables(oldParentUniqueID, elementToAdoptObj.UniqueID);
                //Only foreign references allowed
                referencesTable.RemoveReference(reference);
                //We move the element to a substitute parent.
                referencesTable.AttachedToParent = false;
                //We had a succesfull adoption :)
                return(true);
            }
            return(false);
        }