Пример #1
0
        internal static Argument MorphArgument(ModelItem originalValue, Type targetType)
        {
            Argument morphed = null;
            Argument original = (Argument)originalValue.GetCurrentValue();
            ActivityWithResult originalExpression = original.Expression;
            
            if (originalExpression != null)
            {
                Type expressionType = originalExpression.GetType();
                Type expressionGenericType = expressionType.IsGenericType ? expressionType.GetGenericTypeDefinition() : null;

                if (expressionGenericType != null)
                {       
                    bool isLocation = ExpressionHelper.IsGenericLocationExpressionType(originalExpression);
                    ActivityWithResult morphedExpression;
                    EditingContext context = originalValue.GetEditingContext();
                    morphed = Argument.Create(targetType, original.Direction);
                    if (ExpressionHelper.TryMorphExpression(originalExpression, isLocation, targetType, 
                        context, out morphedExpression))
                    {                        
                        morphed.Expression = morphedExpression;
                    }
                    //[....] 

                }
            }
            return morphed;
        }
        // referenceTransitionModelItem is used when a connector is re-linked.
        void CreateTransition(ConnectionPoint sourceConnPoint, ConnectionPoint destConnPoint, ModelItem referenceTransitionModelItem, bool isSourceMoved)
        {
            Debug.Assert(this.IsOutmostStateContainerEditor(), "Should only be called by the outmost editor.");

            WorkflowViewElement srcDesigner = sourceConnPoint.ParentDesigner as WorkflowViewElement;
            WorkflowViewElement destDesigner = destConnPoint.ParentDesigner as WorkflowViewElement;
            Debug.Assert(srcDesigner is StateDesigner && destDesigner is StateDesigner, "The source and destination designers should both be StateDesigner");

            ModelItem srcModelItem = srcDesigner.ModelItem;
            ModelItem destModelItem = destDesigner.ModelItem;
            ModelItem transitionModelItem = null;

            // We are moving the connector.
            if (referenceTransitionModelItem != null && referenceTransitionModelItem.ItemType == typeof(Transition))
            {
                transitionModelItem = referenceTransitionModelItem;
                // We are moving the start of the connector. We only preserve the trigger if it is not shared.
                if(isSourceMoved)
                {
                    Transition referenceTransition = referenceTransitionModelItem.GetCurrentValue() as Transition;
                    ModelItem stateModelItem = GetParentStateModelItemForTransition(referenceTransitionModelItem);
                    State state = stateModelItem.GetCurrentValue() as State;
                    bool isTriggerShared = false;
                    foreach (Transition transition in state.Transitions)
                    {
                        if (transition != referenceTransition && transition.Trigger == referenceTransition.Trigger)
                        {
                            isTriggerShared = true;
                            break;
                        }
                    }
                    if (isTriggerShared)
                    {
                        transitionModelItem.Properties[TransitionDesigner.TriggerPropertyName].SetValue(null);
                    }
                }
                transitionModelItem.Properties[TransitionDesigner.ToPropertyName].SetValue(destModelItem);
                srcModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(transitionModelItem);
            }
            // We are creating a new connector. 
            else
            {
                Transition newTransition = new Transition() { DisplayName = string.Empty };
                newTransition.To = destModelItem.GetCurrentValue() as State;
                // Assign the shared trigger.
                if (sourceConnPoint.AttachedConnectors.Count > 0)
                {
                    Connector connector = sourceConnPoint.AttachedConnectors[0];
                    Transition existingTransition = StateContainerEditor.GetConnectorModelItem(connector).GetCurrentValue() as Transition;
                    newTransition.Trigger = existingTransition.Trigger;
                }
                transitionModelItem = srcModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(newTransition);
            }
            if (transitionModelItem != null)
            {
                PointCollection connectorViewState = new PointCollection(ConnectorRouter.Route(this.panel, sourceConnPoint, destConnPoint));
                this.StoreConnectorLocationViewState(transitionModelItem, connectorViewState, true);
            }
        }
Пример #3
0
        internal static void EnsureInitialization(ModelItem modelItem)
        {
            Contract.Requires(modelItem != null);

            var value = modelItem.GetCurrentValue();
            var ei = value as IEnsureInitialization;
            if (ei != null) ei.EnsureInitialization();
        }
 protected override IEnumerable<IActionableErrorInfo> ValidateCollectionItem(ModelItem mi)
 {
     var dto = mi.GetCurrentValue() as SharepointSearchTo;
     if(dto == null)
     {
         yield break;
     }
 }
        // Returns the current value of this property.
        // When the object is not primitive, enum, or string we always return the ModelItem wrapping it.
        // this enables nested binding in wpf still go through modelItems tree so taht we can intercept
        // the property sets e.g "{Binding Path=RootModel.ComplexProperty.Blah"}, since we return a ModelItem
        // for ComplexProperty we can still intercept sets made from Wpf controls to Blah even if ComplexProperty
        // type does not implement INotifyPropertyChanged.
        public override object GetValue(object component)
        {
            ModelItem value = this.itemProperty.Value;

            if (value == null)
            {
                return(null);
            }
            Type itemType = value.ItemType;

            if (itemType.IsPrimitive || itemType.IsEnum || itemType.Equals(typeof(String)))
            {
                return(value.GetCurrentValue());
            }
            return(value);
        }
Пример #6
0
        // Performs the actual conversion from one type to antother.  If the value provided
        // is a ModelItem, it will be unwrapped first.  The return value is a ModelItem.
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            ModelItem item = value as ModelItem;

            if (item != null)
            {
                value = item.GetCurrentValue();
            }
            object convertedValue = this.converter.ConvertFrom(WrapContext(context), culture, value);

            if (convertedValue != null)
            {
                convertedValue = this.modelTreeManager.CreateModelItem(null, convertedValue);
            }

            return(convertedValue);
        }
        public override bool Apply()
        {
            Fx.Assert(this.ModelTreeManager != null, "Modeltreemanager cannot be null");
            Fx.Assert(this.Owner != null, "Owner modelitem cannot be null");
            Fx.Assert(!String.IsNullOrEmpty(this.PropertyName), " property name cannot be null or emptry");
            ModelPropertyImpl dataModelProperty = (ModelPropertyImpl)this.Owner.Properties[this.PropertyName];
            ModelItem         oldValue          = dataModelProperty.Value;

            if ((oldValue == null && this.NewValue == null) ||
                (oldValue != null && this.NewValue != null && oldValue.GetCurrentValue().Equals(this.NewValue.GetCurrentValue())))
            {
                return(false);
            }
            dataModelProperty.SetValueCore(this.NewValue);
            ModelChangeInfo changeInfo = ModelChangeInfoImpl.CreatePropertyChanged(this.Owner, this.PropertyName, this.OldValue, this.NewValue);

            this.ModelTreeManager.NotifyPropertyChange(dataModelProperty, changeInfo);
            return(true);
        }
        public override object RetrieveViewState(ModelItem modelItem, string key)
        {
            if (modelItem == null)
            {
                throw FxTrace.Exception.AsError(new ArgumentNullException("modelItem"));
            }
            if (key == null)
            {
                throw FxTrace.Exception.AsError(new ArgumentNullException("key"));
            }

            object viewStateObj = null;
            Dictionary<string, object> viewState = WorkflowViewStateService.GetViewState(modelItem.GetCurrentValue());
            if (viewState != null)
            {
                viewState.TryGetValue(key, out viewStateObj);
            }
            return viewStateObj;
        }
Пример #9
0
        // Returns child properties for a type converter.  This will wrap all properties returned.
        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
        {
            if (value == null)
            {
                throw FxTrace.Exception.AsError(new ArgumentNullException("value"));
            }

            ModelItem item = value as ModelItem;

            if (item != null)
            {
                value = item.GetCurrentValue();
            }

            PropertyDescriptorCollection props = this.converter.GetProperties(WrapContext(context), value, attributes);

            if (props != null && props.Count > 0)
            {
                if (item == null)
                {
                    // We will need the item for this object.
                    item = this.modelTreeManager.CreateModelItem(null, value);
                }

                // Search our item for each property and wrap it.  If
                // a property is not offered by the model, ommit it.

                List <PropertyDescriptor> newProps = new List <PropertyDescriptor>(props.Count);
                foreach (PropertyDescriptor p in props)
                {
                    ModelProperty modelProp = item.Properties.Find(p.Name);
                    if (modelProp != null)
                    {
                        newProps.Add(new ModelPropertyDescriptor(modelProp));
                    }
                }

                props = new PropertyDescriptorCollection(newProps.ToArray(), true);
            }

            return(props);
        }
 public override Dictionary<string, object> RetrieveAllViewState(ModelItem modelItem)
 {
     if (modelItem == null)
     {
         throw FxTrace.Exception.AsError(new ArgumentNullException("modelItem"));
     }
     return WorkflowViewStateService.GetViewState(modelItem.GetCurrentValue());
 }
 ModelItem GetConnectorViewStateStorageModelItem(ModelItem linkModelItem)
 {
     ModelItem storageModelItem = linkModelItem;
     if (typeof(IFlowSwitchLink).IsAssignableFrom(linkModelItem.ItemType))
     {
         IFlowSwitchLink link = (IFlowSwitchLink)linkModelItem.GetCurrentValue();
         //Getting FlowSwitch ModelItem since there is no CFx object for linkModelItem.
         IModelTreeItem modelTreeItem = this.ModelItem as IModelTreeItem;
         storageModelItem = modelTreeItem.ModelTreeManager.WrapAsModelItem(link.ParentFlowSwitch);
     }
     return storageModelItem;
 }
 public DynamicArgumentWrapperObject(string argumentName, ModelItem argumentItem)
 {
     Fx.Assert(argumentItem != null, "argumentItem canot be null");
     this.isInitializing = true;
     this.IsValidating = false;            
     Argument argument = (Argument)argumentItem.GetCurrentValue();
     this.Name = argumentName;
     this.Direction = argument.Direction;
     this.UseLocationExpression = (this.Direction != ArgumentDirection.In);
     this.Type = argument.ArgumentType;
     this.Expression = argumentItem.Properties[ExpressionPropertyName].Value;
     this.isInitializing = false;
 }
 ValidationErrorState GetValidationError(ModelItem modelItem)
 {
     ValidationErrorState validationError = null;
     this.ValidationErrors.TryGetValue(modelItem.GetCurrentValue(), out validationError);
     return validationError;
 }
 private ModelItem DoAutoConnect(UIElement sourceElement, ModelItem droppedModelItem, Transition transitionToCopy, int insertIndex = InvalidIndex)
 {
     ModelItem sourceModelItem = TryGetModelItemFromView(sourceElement);
     if (sourceModelItem != null && droppedModelItem.ItemType == typeof(State))
     {
         if (sourceModelItem.ItemType == typeof(State))
         {
             ModelItem stateMachineModelItem = GetStateMachineModelItem(sourceModelItem);
             Transition transition = new Transition
             {
                 DisplayName = StateContainerEditor.GenerateTransitionName(stateMachineModelItem),
                 To = droppedModelItem.GetCurrentValue() as State
             };
             if (transitionToCopy != null)
             {
                 transition.Action = transitionToCopy.Action;
                 transition.Condition = transitionToCopy.Condition;
                 transition.DisplayName = transitionToCopy.DisplayName;
                 transition.Trigger = transitionToCopy.Trigger;
             }
             ModelItem trasitionModelItem = null;
             if (insertIndex >= 0)
             {
                 trasitionModelItem = sourceModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Insert(insertIndex, transition);
             }
             else
             {
                 trasitionModelItem = sourceModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(transition);
             }
             Fx.Assert(trasitionModelItem != null, "trasitionModelItem");
             return trasitionModelItem;
         }
         // auto-connect from the initial node
         else if (sourceModelItem.ItemType == typeof(StartNode))
         {
             this.ModelItem.Properties[StateMachineDesigner.InitialStatePropertyName].SetValue(droppedModelItem);
             return this.ModelItem;
         }
     }
     return null;
 }
        internal static List<ModelItem> GetVariablesInScope(ModelItem ownerActivity)
        {
            List<ModelItem> declaredVariables = new List<ModelItem>();
            if (ownerActivity != null)
            {
                bool includeArguments = !(ownerActivity.GetCurrentValue() is ActivityBuilder);
                FrameworkName targetFramework = WorkflowDesigner.GetTargetFramework(ownerActivity.GetEditingContext());
                if ((targetFramework != null) && (targetFramework.IsLessThan45()))
                {
                    declaredVariables.AddRange(VariableHelper.FindVariablesInScope(ownerActivity));
                    declaredVariables.AddRange(VariableHelper.FindActivityDelegateArgumentsInScope(ownerActivity));
                    if (includeArguments)
                    {
                        declaredVariables.AddRange(VisualBasicEditor.GetVariablesForArguments(ownerActivity.Root));
                    }
                }
                else
                {
                    declaredVariables.AddRange(VisualBasicEditor.GetVariablesInScopeWithShadowing(ownerActivity, includeArguments));
                }
            }

            return declaredVariables;
        }
        // referenceTransitionModelItem is used when a connector is re-linked.
        void CreateTransition(ConnectionPoint sourceConnPoint, ConnectionPoint destConnPoint, ModelItem referenceTransitionModelItem, bool isSourceMoved)
        {
            VirtualizedContainerService.VirtualizingContainer srcDesigner = sourceConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            Fx.Assert(srcDesigner != null, "srcDesigner should not be null.");
            VirtualizedContainerService.VirtualizingContainer destDesigner = destConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            Fx.Assert(destDesigner != null, "destDesigner should not be null.");

            ModelItem srcModelItem = srcDesigner.ModelItem;
            ModelItem destModelItem = destDesigner.ModelItem;
            ModelItem transitionModelItem = null;

            // We are moving the connector.
            if (referenceTransitionModelItem != null && referenceTransitionModelItem.ItemType == typeof(Transition))
            {
                transitionModelItem = referenceTransitionModelItem;
                // We are moving the start of the connector. We only preserve the trigger if it is not shared.
                if (isSourceMoved)
                {
                    Transition referenceTransition = referenceTransitionModelItem.GetCurrentValue() as Transition;
                    ModelItem stateModelItem = GetParentStateModelItemForTransition(referenceTransitionModelItem);
                    State state = stateModelItem.GetCurrentValue() as State;
                    bool isTriggerShared = false;
                    foreach (Transition transition in state.Transitions)
                    {
                        if (transition != referenceTransition && transition.Trigger == referenceTransition.Trigger)
                        {
                            isTriggerShared = true;
                            break;
                        }
                    }
                    if (isTriggerShared)
                    {
                        transitionModelItem.Properties[TransitionDesigner.TriggerPropertyName].SetValue(null);
                    }
                }
                transitionModelItem.Properties[TransitionDesigner.ToPropertyName].SetValue(destModelItem);
                srcModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(transitionModelItem);
            }
            // We are creating a new connector. 
            else
            {
                ModelItem stateMachineModelItem = GetStateMachineModelItem(srcModelItem);
                Transition newTransition = new Transition() { DisplayName = StateContainerEditor.GenerateTransitionName(stateMachineModelItem) };
                newTransition.To = destModelItem.GetCurrentValue() as State;
                // Assign the shared trigger.
                if (sourceConnPoint.AttachedConnectors.Count > 0)
                {
                    Connector connector = sourceConnPoint.AttachedConnectors[0];
                    Transition existingTransition = StateContainerEditor.GetConnectorModelItem(connector).GetCurrentValue() as Transition;
                    newTransition.Trigger = existingTransition.Trigger;
                }
                transitionModelItem = srcModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(newTransition);
            }
            if (transitionModelItem != null)
            {
                // if the transition connection is re-routed, the SrcConnPointIndex needs to be updated.
                PointCollection connectorViewState = new PointCollection(ConnectorRouter.Route(this.panel, sourceConnPoint, destConnPoint));
                int srcConnectionPointIndex = StateContainerEditor.GetConnectionPoints(sourceConnPoint.ParentDesigner).IndexOf(sourceConnPoint);
                int destConnectionPointIndex = StateContainerEditor.GetConnectionPoints(destConnPoint.ParentDesigner).IndexOf(destConnPoint);
                this.StoreConnectorLocationViewState(transitionModelItem, connectorViewState, true);
                this.ViewStateService.StoreViewStateWithUndo(transitionModelItem, SrcConnectionPointIndexStateKey, srcConnectionPointIndex);
                this.ViewStateService.StoreViewStateWithUndo(transitionModelItem, DestConnectionPointIndexStateKey, destConnectionPointIndex);
            }
        }
        private void RemoveCore(ModelItem key, bool updateInstance)
        {
            try
            {
                this.EditInProgress = true;
                Fx.Assert(this.instance != null, "instance should not be null");
                ModelItem value = this.modelItems[key];
                this.modelItems.Remove(key);

                if (key != null && !this.IsInKeysOrValuesCollection(key))
                {
                    this.modelTreeManager.OnItemEdgeRemoved(this, key);
                }

                if (value != null && !this.IsInKeysOrValuesCollection(value) && value != key)
                {
                    this.modelTreeManager.OnItemEdgeRemoved(this, value);
                }

                if (updateInstance)
                {
                    ModelItemCollectionImpl itemsCollectionImpl = ItemsCollectionModelItemCollection as ModelItemCollectionImpl;
                    if (ItemsCollectionObject != null && itemsCollectionImpl != null)
                    {
                        try
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = false;

                            ModelItem itemToBeRemoved = null;
                            foreach (ModelItem item in itemsCollectionImpl)
                            {
                                ModelItem keyInCollection = item.Properties["Key"].Value;

                                if (key == keyInCollection)
                                {
                                    itemToBeRemoved = item;
                                    break;
                                }

                                if (key != null && keyInCollection != null)
                                {
                                    object keyValue = key.GetCurrentValue();

                                    // ValueType do not share ModelItem, a ModelItem is always created for a ValueType
                                    // ModelTreeManager always create a ModelItem even for the same string
                                    // So, we compare object instance instead of ModelItem for above cases.
                                    if (keyValue is ValueType || keyValue is string)
                                    {
                                        if (keyValue.Equals(keyInCollection.GetCurrentValue()))
                                        {
                                            itemToBeRemoved = item;
                                            break;
                                        }
                                    }
                                }
                            }

                            if (itemToBeRemoved != null)
                            {
                                itemsCollectionImpl.RemoveCore(itemToBeRemoved);
                            }
                        }
                        finally
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = true;
                        }
                    }
                    this.instance.Remove(key == null ? null : key.GetCurrentValue());
                }
                if (null != this.CollectionChanged)
                {
                    this.CollectionChanged(this,
                        new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, new KeyValuePair<ModelItem, ModelItem>(key, value)));
                }
            }
            finally
            {
                this.EditInProgress = false;
            }
        }
        private void AddCore(ModelItem key, ModelItem value, bool updateInstance)
        {
            try
            {
                this.EditInProgress = true;
                Fx.Assert(this.instance != null, "instance should not be null");
                
                bool wasKeyInKeysOrValuesCollection = key != null && this.IsInKeysOrValuesCollection(key);
                bool wasValueInKeysOrValuesCollection = value != null && this.IsInKeysOrValuesCollection(value);

                if (updateInstance)
                {
                    //no need to [....] if the ItemsCollection is not DictionaryItemsCollection wrapped by ModelItemCollectionImpl
                    ModelItemCollectionImpl itemsCollectionImpl = this.ItemsCollectionModelItemCollection as ModelItemCollectionImpl;
                    if (ItemsCollectionObject != null && itemsCollectionImpl != null)
                    {
                        try
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = false;
                            object mutableKVPair = Activator.CreateInstance(this.ItemsCollectionKVPType, new object[] { key == null ? null : key.GetCurrentValue(), value != null ? value.GetCurrentValue() : null });
                            ModelItem mutableKVPairItem = this.modelTreeManager.WrapAsModelItem(mutableKVPair);

                            itemsCollectionImpl.AddCore(mutableKVPairItem);
                        }
                        finally
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = true;
                        }
                    }
                    this.instance.Add(key == null ? null : key.GetCurrentValue(), null != value ? value.GetCurrentValue() : null);
                }

                this.modelItems.Add(key, value);

                if (key != null && !wasKeyInKeysOrValuesCollection)
                {
                    this.modelTreeManager.OnItemEdgeAdded(this, key);
                }

                if (value != null && !wasValueInKeysOrValuesCollection && value != key)
                {
                    this.modelTreeManager.OnItemEdgeAdded(this, value);
                }

                if (null != this.CollectionChanged)
                {
                    this.CollectionChanged(this,
                        new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,
                        new KeyValuePair<ModelItem, ModelItem>(key, value)));
                }
            }
            finally
            {
                this.EditInProgress = false;
            }
        }
        private void EditCore(ModelItem key, ModelItem value, bool updateInstance)
        {
            try
            {
                ModelItem oldValue = this.modelItems[key];
                this.EditInProgress = true;
                Fx.Assert(this.instance != null, "instance should not be null");

                bool wasValueInKeysOrValuesCollection = this.IsInKeysOrValuesCollection(value);

                if (updateInstance)
                {
                    this.instance[(key == null) ? null : key.GetCurrentValue()] = null != value ? value.GetCurrentValue() : null;
                    //this also makes sure ItemsCollectionModelItemCollection is not null 
                    if (ItemsCollectionObject != null)
                    {
                        try
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = false;

                            foreach (ModelItem item in ItemsCollectionModelItemCollection)
                            {
                                ModelItem keyInCollection = item.Properties["Key"].Value;
                                bool found = (key == keyInCollection);

                                if (!found && key != null && keyInCollection != null)
                                {
                                    object keyValue = key.GetCurrentValue();

                                    // ValueType do not share ModelItem, a ModelItem is always created for a ValueType
                                    // ModelTreeManager always create a ModelItem even for the same string
                                    // So, we compare object instance instead of ModelItem for above cases.
                                    if (keyValue is ValueType || keyValue is string)
                                    {
                                        found = keyValue.Equals(keyInCollection.GetCurrentValue());
                                    }
                                }

                                if (found)
                                {
                                    ModelPropertyImpl valueImpl = item.Properties["Value"] as ModelPropertyImpl;
                                    if (valueImpl != null)
                                    {
                                        valueImpl.SetValueCore(value);
                                    }
                                }
                            }
                        }
                        finally
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = true;
                        }
                    }
                }

                this.modelItems[key] = null;
                if (oldValue != null && !this.IsInKeysOrValuesCollection(oldValue))
                {
                    this.modelTreeManager.OnItemEdgeRemoved(this, oldValue);
                }

                this.modelItems[key] = value;
                if (value != null && !wasValueInKeysOrValuesCollection)
                {
                    this.modelTreeManager.OnItemEdgeAdded(this, value);
                }

                if (null != this.CollectionChanged)
                {
                    this.CollectionChanged(this,
                        new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace,
                        new KeyValuePair<ModelItem, ModelItem>(key, value),
                        new KeyValuePair<ModelItem, ModelItem>(key, oldValue)));
                }
            }
            finally
            {
                this.EditInProgress = false;
            }
        }
Пример #20
0
        private void RemoveCore(ModelItem key, bool updateInstance)
        {
            try
            {
                this.EditInProgress = true;
                Fx.Assert(this.instance != null, "instance should not be null");
                ModelItem value = this.modelItems[key];
                this.modelItems.Remove(key);

                if (key != null && !this.IsInKeysOrValuesCollection(key))
                {
                    this.modelTreeManager.OnItemEdgeRemoved(this, key);
                }

                if (value != null && !this.IsInKeysOrValuesCollection(value) && value != key)
                {
                    this.modelTreeManager.OnItemEdgeRemoved(this, value);
                }

                if (updateInstance)
                {
                    ModelItemCollectionImpl itemsCollectionImpl = ItemsCollectionModelItemCollection as ModelItemCollectionImpl;
                    if (ItemsCollectionObject != null && itemsCollectionImpl != null)
                    {
                        try
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = false;

                            ModelItem itemToBeRemoved = null;
                            foreach (ModelItem item in itemsCollectionImpl)
                            {
                                ModelItem keyInCollection = item.Properties["Key"].Value;

                                if (key == keyInCollection)
                                {
                                    itemToBeRemoved = item;
                                    break;
                                }

                                if (key != null && keyInCollection != null)
                                {
                                    object keyValue = key.GetCurrentValue();

                                    // ValueType do not share ModelItem, a ModelItem is always created for a ValueType
                                    // ModelTreeManager always create a ModelItem even for the same string
                                    // So, we compare object instance instead of ModelItem for above cases.
                                    if (keyValue is ValueType || keyValue is string)
                                    {
                                        if (keyValue.Equals(keyInCollection.GetCurrentValue()))
                                        {
                                            itemToBeRemoved = item;
                                            break;
                                        }
                                    }
                                }
                            }

                            if (itemToBeRemoved != null)
                            {
                                itemsCollectionImpl.RemoveCore(itemToBeRemoved);
                            }
                        }
                        finally
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = true;
                        }
                    }
                    this.instance.Remove(key == null ? null : key.GetCurrentValue());
                }
                if (null != this.CollectionChanged)
                {
                    this.CollectionChanged(this,
                                           new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, new KeyValuePair <ModelItem, ModelItem>(key, value)));
                }
            }
            finally
            {
                this.EditInProgress = false;
            }
        }
Пример #21
0
        private void DeleteModelItem(ModelItem modelItem)
        {
            if (modelItem != null)
            {
                BreakpointTypes breakpointType;
                if (this.breakpoints.TryGetValue(modelItem, out breakpointType))
                {
                    this.transientBreakpoints[modelItem] = breakpointType;   // cache it in case it's added later (move case).
                    SetBreakpointType(modelItem, BreakpointTypes.None); // clear breakpoint
                }

                DeleteFromMapping(modelItem.GetCurrentValue());
            }
        }
 public override void StoreViewState(ModelItem modelItem, string key, object value)
 {
     if (modelItem == null)
     {
         throw FxTrace.Exception.AsError(new ArgumentNullException("modelItem"));
     }
     if (key == null)
     {
         throw FxTrace.Exception.AsError(new ArgumentNullException("key"));
     }
   
     object oldValue = null;
     Dictionary<string, object> viewState = WorkflowViewStateService.GetViewState(modelItem.GetCurrentValue());
     if (viewState == null)
     {
         viewState = new Dictionary<string, object>();
         WorkflowViewStateService.SetViewState(modelItem.GetCurrentValue(), viewState);
     }
     viewState.TryGetValue(key, out oldValue);
     if (value != null)
     {
         viewState[key] = value;
     }
     else
     {
         RemoveViewState(modelItem, key);
     }
     if (this.ViewStateChanged != null && value != oldValue)
     {
         this.ViewStateChanged(this, new ViewStateChangedEventArgs(modelItem, key, value, oldValue));
     }
 }
Пример #23
0
 /// <summary>
 /// Set Activity according ModelItem
 /// </summary>
 /// <param name="model"></param>
 private void SetActivityFromModelItem(ModelItem model)
 {
     if (model.ItemType == (typeof(FlowStep)))
     {
         FlowStep act = model.GetCurrentValue() as FlowStep;
         Activity = act.Action;
         Model = model.Properties[ModelItemService.ActionPropertyName].Value as ModelItem;
     }
     else if (model.ItemType.IsSubclassOf(typeof(ActivityDelegate)))
     {
         ActivityDelegate act = model.GetCurrentValue() as ActivityDelegate;
         if (act.Handler != null)
         {
             Activity = act.Handler;
             Model = model.Properties[ModelItemService.HandlerPropertyName].Value as ModelItem;
         }
         else
         {
             Activity = model.GetCurrentValue();
             Model = model;
         }
     }
     else
     {
         Activity = model.GetCurrentValue();
         Model = model;
     }
 }
        internal object SetValueCore(ModelItem newValueModelItem)
        {
            object newValueInstance = (newValueModelItem == null) ? null : newValueModelItem.GetCurrentValue();
            ModelItem oldValueModelItem = this.Value;
            IModelTreeItem parent = (IModelTreeItem)this.Parent;

            // update object instance
            this.PropertyDescriptor.SetValue(this.Parent.GetCurrentValue(), newValueInstance);

            if (oldValueModelItem != null && !this.isAttached)
            {
                parent.ModelPropertyStore.Remove(this.Name);
                parent.ModelTreeManager.OnPropertyEdgeRemoved(this.Name, this.Parent, oldValueModelItem);
            }

            if (newValueModelItem != null && !this.isAttached)
            {
                parent.ModelPropertyStore.Add(this.Name, newValueModelItem);
                parent.ModelTreeManager.OnPropertyEdgeAdded(this.Name, this.Parent, newValueModelItem);
            }

            // notify observers
            ((IModelTreeItem)this.Parent).OnPropertyChanged(this.Name);
            return newValueInstance;
        }
        internal void RemoveCore(ModelItem item)
        {

            Fx.Assert(instance is IList, "Instance needs to be IList for remove to work");
            Fx.Assert(instance != null, "instance should not be null");

            IList instanceList = (IList)instance;
            int index = instanceList.IndexOf(item.GetCurrentValue());
            instanceList.Remove(item.GetCurrentValue());
            this.modelItems.Remove(item);

            if (!this.modelItems.Contains(item))
            {
                this.modelTreeManager.OnItemEdgeRemoved(this, item);
            }

            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs("Count"));
            }

            if (this.CollectionChanged != null)
            {
                this.CollectionChanged(this, new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Remove, item, index));
            }
        }
 private static SourceLocation FindMatchSrcLocation(ModelItem modelItem, Dictionary<object, SourceLocation> mapping)
 {
     object modelObject = modelItem.GetCurrentValue();
     return FindSrcLocation(mapping, (key) =>
         {
             return object.ReferenceEquals(modelObject, key);
         });
 }
        bool CreateFlowSwitchLink(ConnectionPoint sourceConnPoint, ModelItem srcFlowElementMI, ModelItem destFlowElementMI, IFlowSwitchLink caseKey, PointCollection connectorViewState, ref string errorMessage)
        {
            IModelTreeItem modelTreeItem = this.ModelItem as IModelTreeItem;
            if ((caseKey != null && caseKey.IsDefaultCase) || (caseKey == null && srcFlowElementMI.Properties["Default"].Value == null))
            {
                IFlowSwitchLink link = GenericFlowSwitchHelper.CreateFlowSwitchLink(srcFlowElementMI.ItemType, srcFlowElementMI, null, true);
                ModelItem linkModelItem = new FakeModelItemImpl(modelTreeItem.ModelTreeManager, link.GetType(), link, null);
                link.ModelItem = linkModelItem;
                if (connectorViewState != null)
                {
                    this.StoreConnectorViewState(linkModelItem, connectorViewState, sourceConnPoint);
                }
                srcFlowElementMI.Properties["Default"].SetValue(destFlowElementMI);
            }
            else
            {
                ModelProperty casesProp = srcFlowElementMI.Properties["Cases"];

                string uniqueCaseName = null;

                if (caseKey == null)
                {
                    Type typeArgument = srcFlowElementMI.ItemType.GetGenericArguments()[0];
                    if (GenericFlowSwitchHelper.CanBeGeneratedUniquely(typeArgument))
                    {
                        uniqueCaseName = GenericFlowSwitchHelper.GetCaseName(casesProp, typeArgument, out errorMessage);
                    }
                    else
                    {
                        FlowSwitchCaseEditorDialog editor = new FlowSwitchCaseEditorDialog(srcFlowElementMI, this.Context, this, SR.AddNewCase, typeArgument);
                        editor.WindowSizeToContent = SizeToContent.WidthAndHeight;
                        if (!editor.ShowOkCancel())
                        {
                            return false;
                        }
                        uniqueCaseName = editor.CaseName;
                    }
                }
                else
                {
                    uniqueCaseName = caseKey.CaseName;
                }

                if (string.IsNullOrEmpty(errorMessage))
                {
                    IFlowSwitchLink link = GenericFlowSwitchHelper.CreateFlowSwitchLink(srcFlowElementMI.ItemType, srcFlowElementMI, uniqueCaseName, false);
                    ModelItem linkModelItem = new FakeModelItemImpl(modelTreeItem.ModelTreeManager, link.GetType(), link, null);
                    link.ModelItem = linkModelItem;
                    if (connectorViewState != null)
                    {
                        this.StoreConnectorViewState(linkModelItem, connectorViewState, sourceConnPoint);
                    }
                    GenericFlowSwitchHelper.AddCase(srcFlowElementMI.Properties["Cases"], link.CaseObject, destFlowElementMI.GetCurrentValue());
                }
            }
            return true;
        }
        internal void InsertCore(int index, ModelItem item)
        {
            Fx.Assert(instance is IList, "instance needs to be IList");
            Fx.Assert(instance != null, "instance should not be null");
            IList instanceList = (IList)instance;
            instanceList.Insert(index, item.GetCurrentValue());

            bool wasInCollection = this.modelItems.Contains(item);
            
            this.modelItems.Insert(index, item);

            if (!wasInCollection)
            {
                this.modelTreeManager.OnItemEdgeAdded(this, item);
            }

            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs("Count"));
            }
            if (this.CollectionChanged != null)
            {
                this.CollectionChanged(this, new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Add, item, index));
            }
        }
 //Returns a new connector if viewstate exists, null otherwise.
 Connector GetConnectorViewState(UIElement source, UIElement dest, ModelItem linkModelItem, ConnectionPoint sourceConnectionPoint)
 {
     Fx.Assert(this.panel != null, "This code should not be hit if panel is null");
     Connector connector = null;
     object connectorLocation = null;
     if (typeof(FlowDecision).IsAssignableFrom(linkModelItem.ItemType))
     {
         Fx.Assert(sourceConnectionPoint != null, "Source connection point is null.");
         if (sourceConnectionPoint.Equals(FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[linkModelItem])))
         {
             connectorLocation = this.ViewStateService.RetrieveViewState(linkModelItem, TrueConnectorViewStateKey);
         }
         else
         {
             connectorLocation = this.ViewStateService.RetrieveViewState(linkModelItem, FalseConnectorViewStateKey);
         }
     }
     else if (typeof(IFlowSwitchLink).IsAssignableFrom(linkModelItem.ItemType))
     {
         string key = null;
         IFlowSwitchLink link = (IFlowSwitchLink)linkModelItem.GetCurrentValue();
         if (link.IsDefaultCase)
         {
             key = FlowSwitchDefaultViewStateKey;
         }
         else
         {
             key = link.CaseName + CaseViewStateKeyAppendString;
         }
         //Transitioning from fake ModelItem world to real ModelItem world.
         ModelItem realFSModelItem = (this.ModelItem as IModelTreeItem).ModelTreeManager.WrapAsModelItem(link.ParentFlowSwitch);
         connectorLocation = this.ViewStateService.RetrieveViewState(realFSModelItem, key);
     }
     else
     {
         connectorLocation = this.ViewStateService.RetrieveViewState(linkModelItem, ConnectorViewStateKey);
     }
     PointCollection locationPts = connectorLocation as PointCollection;
     if (locationPts != null)
     {
         ConnectionPoint srcConnPoint, destConnPoint;
         System.Diagnostics.Debug.WriteLine(this.isLoaded ? "About to call ConnectionPointHitTest - Loaded" : "About to call ConnectionPointHitTest - Not Loaded");
         srcConnPoint = ConnectionPointHitTest(source, locationPts[0]);
         destConnPoint = ConnectionPointHitTest(dest, locationPts[locationPts.Count - 1]);
         //In Debug mode, the size of the designer changes due to the debug adorner(border). Because of this connection points will move and
         //won't coincide with the viewstate.
         //The following code path is added for the scenario where we reload the flowchart designer by navigating back and forth on breadcrumb
         //when one of the flowchart activities has the debug border.
         //In this scenario we try to find the closest connection point from the end point stored in viewstate. If the distance between the two
         //is within the acceptable range, we will reuse the viewstate and avoid re-drawing the connector.
         if (this.IsReadOnly)
         {
             ConnectionPoint pt;
             double dist;
             if (srcConnPoint == null)
             {
                 pt = FindClosestConnectionPoint(locationPts[0], FlowchartDesigner.GetConnectionPoints(source), out dist);
                 if (pt != null && pt.PointType != ConnectionPointKind.Incoming && dist <= DebugTimeMaxConnectorShapeDist)
                 {
                     srcConnPoint = pt;
                 }
             }
             if (destConnPoint == null)
             {
                 pt = FindClosestConnectionPoint(locationPts[locationPts.Count - 1], FlowchartDesigner.GetConnectionPoints(dest), out dist);
                 if (pt != null && pt.PointType != ConnectionPointKind.Outgoing && dist <= DebugTimeMaxConnectorShapeDist)
                 {
                     destConnPoint = pt;
                 }
             }
         }
         if (srcConnPoint != null && destConnPoint != null)
         {
             connector = GetConnector(linkModelItem, srcConnPoint, destConnPoint);
             connector.Points = locationPts;
         }
     }
     return connector;
 }
 internal static ObservableCollection<DynamicArgumentWrapperObject> ModelItemToWrapperCollection(ModelItem model, out bool isDictionary, out Type underlyingArgumentType)
 {
     string errorMessage = string.Empty;
     underlyingArgumentType = null;
     isDictionary = false;
     if (model is ModelItemCollection)
     {
         underlyingArgumentType = model.GetCurrentValue().GetType().GetGenericArguments()[0];
         if (!typeof(Argument).IsAssignableFrom(underlyingArgumentType))
         {
             errorMessage = SR.NonSupportedDynamicArgumentType;
         }
     }
     else if (model is ModelItemDictionary)
     {
         Type underlyingKeyType = model.GetCurrentValue().GetType().GetGenericArguments()[0];
         underlyingArgumentType = model.GetCurrentValue().GetType().GetGenericArguments()[1];
         if (!typeof(Argument).IsAssignableFrom(underlyingArgumentType))
         {
             errorMessage = SR.NonSupportedDynamicArgumentType;
         }
         if (underlyingKeyType != typeof(string))
         {
             errorMessage += SR.NonSupportedDynamicArgumentKeyType;
         }
         isDictionary = true;
     }
     else
     {
         errorMessage = SR.NonSupportedModelItemCollectionOrDictionary;
     }
     if (!string.IsNullOrEmpty(errorMessage))
     {
         ErrorReporting.ShowErrorMessage(SR.NonSupportedModelItemCollectionOrDictionary);
         return null;
     }
     if (isDictionary)
     {
         ObservableCollection<DynamicArgumentWrapperObject> wrappers = new ObservableCollection<DynamicArgumentWrapperObject>();
         foreach (ModelItem item in GetArgumentCollection(model))
         {
             wrappers.Add(new DynamicArgumentWrapperObject(item.Properties["Key"].ComputedValue as string, item.Properties["Value"].Value));
         }
         return wrappers;
     }
     else
     {
         ObservableCollection<DynamicArgumentWrapperObject> wrappers = new ObservableCollection<DynamicArgumentWrapperObject>();
         foreach (ModelItem item in GetArgumentCollection(model))
         {
             wrappers.Add(new DynamicArgumentWrapperObject(null, item));
         }
         return wrappers;
     }
 }
Пример #31
0
        private void AddCore(ModelItem key, ModelItem value, bool updateInstance)
        {
            try
            {
                this.EditInProgress = true;
                Fx.Assert(this.instance != null, "instance should not be null");

                bool wasKeyInKeysOrValuesCollection   = key != null && this.IsInKeysOrValuesCollection(key);
                bool wasValueInKeysOrValuesCollection = value != null && this.IsInKeysOrValuesCollection(value);

                if (updateInstance)
                {
                    //no need to [....] if the ItemsCollection is not DictionaryItemsCollection wrapped by ModelItemCollectionImpl
                    ModelItemCollectionImpl itemsCollectionImpl = this.ItemsCollectionModelItemCollection as ModelItemCollectionImpl;
                    if (ItemsCollectionObject != null && itemsCollectionImpl != null)
                    {
                        try
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = false;
                            object    mutableKVPair     = Activator.CreateInstance(this.ItemsCollectionKVPType, new object[] { key == null ? null : key.GetCurrentValue(), value != null ? value.GetCurrentValue() : null });
                            ModelItem mutableKVPairItem = this.modelTreeManager.WrapAsModelItem(mutableKVPair);

                            itemsCollectionImpl.AddCore(mutableKVPairItem);
                        }
                        finally
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = true;
                        }
                    }
                    this.instance.Add(key == null ? null : key.GetCurrentValue(), null != value ? value.GetCurrentValue() : null);
                }

                this.modelItems.Add(key, value);

                if (key != null && !wasKeyInKeysOrValuesCollection)
                {
                    this.modelTreeManager.OnItemEdgeAdded(this, key);
                }

                if (value != null && !wasValueInKeysOrValuesCollection && value != key)
                {
                    this.modelTreeManager.OnItemEdgeAdded(this, value);
                }

                if (null != this.CollectionChanged)
                {
                    this.CollectionChanged(this,
                                           new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add,
                                                                                new KeyValuePair <ModelItem, ModelItem>(key, value)));
                }
            }
            finally
            {
                this.EditInProgress = false;
            }
        }
 string GetConnectorViewStateKey(ModelItem linkModelItem, ConnectionPoint srcConnPoint)
 {
     string viewStateKey = ConnectorViewStateKey;
     if ((typeof(FlowDecision).IsAssignableFrom(linkModelItem.ItemType)))
     {
         if (srcConnPoint.Equals(FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[linkModelItem])))
         {
             viewStateKey = TrueConnectorViewStateKey;
         }
         else
         {
             viewStateKey = FalseConnectorViewStateKey;
         }
     }
     else if (typeof(IFlowSwitchLink).IsAssignableFrom(linkModelItem.ItemType))
     {
         IFlowSwitchLink link = (IFlowSwitchLink)linkModelItem.GetCurrentValue();
         if (link.IsDefaultCase)
         {
             viewStateKey = FlowSwitchDefaultViewStateKey;
         }
         else
         {
             viewStateKey = link.CaseName + CaseViewStateKeyAppendString;
         }
     }
     return viewStateKey;
 }
 public override bool RemoveViewState(ModelItem modelItem, string key)
 {
     if (modelItem == null)
     {
         throw FxTrace.Exception.AsError(new ArgumentNullException("modelItem"));
     }
     if (key == null)
     {
         throw FxTrace.Exception.AsError(new ArgumentNullException("key"));
     }
     bool itemRemoved = false;
     Dictionary<string, object> viewState = WorkflowViewStateService.GetViewState(modelItem.GetCurrentValue());
     if (viewState != null && key != null && viewState.ContainsKey(key))
     {
         itemRemoved = viewState.Remove(key);
         if (viewState.Keys.Count == 0)
         {
             AttachablePropertyServices.RemoveProperty(modelItem.GetCurrentValue(), ViewStateName);
         }
     }
     return itemRemoved;
 }
        void SetConnectorLabel(Connector connector, ConnectionPoint srcConnPoint, ModelItem linkModelItem)
        {
            BindingBase labelBinding = null;

            if (typeof(FlowDecision).IsAssignableFrom(linkModelItem.ItemType))
            {
                if (FlowchartDesigner.GetTrueConnectionPoint(srcConnPoint.ParentDesigner).Equals(srcConnPoint))
                {
                    labelBinding = new Binding { Source = linkModelItem, Path = new PropertyPath("TrueLabel") };
                }
                else
                {
                    labelBinding = new Binding { Source = linkModelItem, Path = new PropertyPath("FalseLabel") };
                }

                SetConnectorLabelToolTip(connector, labelBinding);
            }
            else if (typeof(IFlowSwitchLink).IsAssignableFrom(linkModelItem.ItemType))
            {
                IFlowSwitchLink flowSwitchLink = (IFlowSwitchLink)linkModelItem.GetCurrentValue();
                labelBinding = flowSwitchLink.CreateConnectorLabelTextBinding();
                SetConnectorLabelToolTip(connector, labelBinding);
            }
        }
Пример #35
0
        private static void MergeTaskArgmentToParent(ModelItem taskItem, ModelItem rootItem, ModelItem selected)
        {
            var taskArgments = ArgumentService.GetArgument(taskItem.GetCurrentValue() as ActivityBuilder);
            var rootArgments = ArgumentService.GetArgument(rootItem.GetCurrentValue() as ActivityBuilder);
            List<Variable> variables = ArgumentService.GetAvailableVariables(selected).ToList();

            DoSameNameVariables(
                taskArgments.Except(rootArgments, new DynamicActivityPropertyEqualityComparer()),
                variables,
                taskItem,
                rootItem,
                selected);
        }
        private bool CanPasteTransition(ModelItem sourceStateItem, out string errorMessage)
        {
            Fx.Assert(sourceStateItem != null, "sourceStateItem cannot be null");

            if (sourceStateItem.ItemType != typeof(State))
            {
                errorMessage = SR.PasteTransitionOnNonStateItem;
                return false;
            }

            if (!this.modelItemToUIElement.ContainsKey(sourceStateItem))
            {
                errorMessage = SR.PasteTransitionWithoutDestinationState;
                return false;
            }

            State sourceState = (State)sourceStateItem.GetCurrentValue();

            if (sourceState.IsFinal)
            {
                errorMessage = SR.PasteTransitionOnFinalState;
                return false;
            }

            if (GetEmptyConnectionPoints(sourceStateItem.View as UIElement).Count < 1)
            {
                errorMessage = string.Format(CultureInfo.CurrentUICulture, SR.PasteTransitionWithoutAvailableConnectionPoints, sourceState.DisplayName);
                return false;
            }

            errorMessage = null;
            return true;
        }
Пример #37
0
        private void EditCore(ModelItem key, ModelItem value, bool updateInstance)
        {
            try
            {
                ModelItem oldValue = this.modelItems[key];
                this.EditInProgress = true;
                Fx.Assert(this.instance != null, "instance should not be null");

                bool wasValueInKeysOrValuesCollection = this.IsInKeysOrValuesCollection(value);

                if (updateInstance)
                {
                    this.instance[(key == null) ? null : key.GetCurrentValue()] = null != value?value.GetCurrentValue() : null;

                    //this also makes sure ItemsCollectionModelItemCollection is not null
                    if (ItemsCollectionObject != null)
                    {
                        try
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = false;

                            foreach (ModelItem item in ItemsCollectionModelItemCollection)
                            {
                                ModelItem keyInCollection = item.Properties["Key"].Value;
                                bool      found           = (key == keyInCollection);

                                if (!found && key != null && keyInCollection != null)
                                {
                                    object keyValue = key.GetCurrentValue();

                                    // ValueType do not share ModelItem, a ModelItem is always created for a ValueType
                                    // ModelTreeManager always create a ModelItem even for the same string
                                    // So, we compare object instance instead of ModelItem for above cases.
                                    if (keyValue is ValueType || keyValue is string)
                                    {
                                        found = keyValue.Equals(keyInCollection.GetCurrentValue());
                                    }
                                }

                                if (found)
                                {
                                    ModelPropertyImpl valueImpl = item.Properties["Value"] as ModelPropertyImpl;
                                    if (valueImpl != null)
                                    {
                                        valueImpl.SetValueCore(value);
                                    }
                                }
                            }
                        }
                        finally
                        {
                            ItemsCollectionObject.ShouldUpdateDictionary = true;
                        }
                    }
                }

                this.modelItems[key] = null;
                if (oldValue != null && !this.IsInKeysOrValuesCollection(oldValue))
                {
                    this.modelTreeManager.OnItemEdgeRemoved(this, oldValue);
                }

                this.modelItems[key] = value;
                if (value != null && !wasValueInKeysOrValuesCollection)
                {
                    this.modelTreeManager.OnItemEdgeAdded(this, value);
                }

                if (null != this.CollectionChanged)
                {
                    this.CollectionChanged(this,
                                           new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace,
                                                                                new KeyValuePair <ModelItem, ModelItem>(key, value),
                                                                                new KeyValuePair <ModelItem, ModelItem>(key, oldValue)));
                }
            }
            finally
            {
                this.EditInProgress = false;
            }
        }