internal static TreeViewItemViewModel Expand(TreeViewItemModelItemViewModel rootTreeViewItem, ModelItem modelItemToExpandTo)
        {
            Fx.Assert(modelItemToExpandTo != null && rootTreeViewItem != null, "rootTreeViewItem and modelItemToExpand should not have null value");

            // ModelItems with HidePropertyInOutlineViewAttribute are invisible in the designerTree.
            if (ExtensibilityAccessor.GetAttribute <HidePropertyInOutlineViewAttribute>(modelItemToExpandTo) != null)
            {
                return(null);
            }

            Stack pathStack = new Stack();

            TreeViewItemViewModel itemToBeSelected = null;

            if (GetExpandingPath(modelItemToExpandTo, pathStack, new HashSet <ModelItem>()))
            {
                // If the root of modelItemToExpandTo differs from the root of the designerTree, it means modelItemToExpandTo doesn't belong to the designerTree.
                if (pathStack.Pop() != rootTreeViewItem.VisualValue)
                {
                    return(null);
                }

                object item = null;
                TreeViewItemViewModel treeViewItem     = rootTreeViewItem;
                TreeViewItemViewModel tempTreeViewItem = rootTreeViewItem;

                // Using the path to the root, expand the corresponding tree node. Ignore the items which is not visible on the designerTree.
                while (pathStack.Count > 0)
                {
                    if (tempTreeViewItem != null)
                    {
                        treeViewItem            = tempTreeViewItem;
                        treeViewItem.IsExpanded = true;
                    }

                    item             = pathStack.Pop();
                    tempTreeViewItem = (from child in treeViewItem.Children
                                        where (child is TreeViewItemModelItemViewModel && ((TreeViewItemModelItemViewModel)child).VisualValue == item as ModelItem) ||
                                        (child is TreeViewItemModelPropertyViewModel && ((TreeViewItemModelPropertyViewModel)child).VisualValue == item as ModelProperty) ||
                                        (child is TreeViewItemKeyValuePairModelItemViewModel && ((TreeViewItemKeyValuePairModelItemViewModel)child).VisualValue.Value == item as ModelItem)
                                        select child).FirstOrDefault();

                    // For TreeViewItemKeyValuePairModelItemViewModel, its path to the children is very complicated.
                    // Take Switch as example: Switch(ModelItem) -> Cases(ModelProperty) -> KeyDictionaryCollection(ModelItem) -> ItemsCollection(ModelProperty) -> ModelItemKeyValuePair<T, Activity>(ModelItem) -> Value(ModelProperty) -> Children
                    // All the path nodes except Switch and Children are invisible and can be ignored, the child node in the path is used twice to search for TreeViewItemKeyValuePairModelItemViewModel and its children in designerTree.
                    if (tempTreeViewItem is TreeViewItemKeyValuePairModelItemViewModel)
                    {
                        // For further searching
                        pathStack.Push(item);
                    }

                    if (pathStack.Count == 0)
                    {
                        itemToBeSelected = tempTreeViewItem;
                    }
                }
            }

            return(itemToBeSelected);
        }
Пример #2
0
        internal static bool IsPromotedProperty(ModelItem modelItem, string propertyName)
        {
            ShowInOutlineViewAttribute attr = ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(modelItem);

            if (attr != null && !string.IsNullOrEmpty(attr.PromotedProperty))
            {
                return(string.Equals(propertyName, attr.PromotedProperty, StringComparison.Ordinal));
            }
            return(false);
        }
Пример #3
0
        internal static T GetAttribute <T>(Type type) where T : Attribute
        {
            T attribute = ExtensibilityAccessor.GetAttribute <T>(type);

            if (attribute == null && type.IsGenericType)
            {
                attribute = ExtensibilityAccessor.GetAttribute <T>(type.GetGenericTypeDefinition());
            }
            return(attribute);
        }
        static Type ResolveGenericParameters(DependencyObject dropTarget, EditingContext context, Type type)
        {
            // look to see if there is a DefaultTypeArgumentAttribute on it
            DefaultTypeArgumentAttribute typeArgumentAttribute = ExtensibilityAccessor.GetAttribute <DefaultTypeArgumentAttribute>(type);

            if (typeArgumentAttribute != null && typeArgumentAttribute.Type != null)
            {
                type = type.MakeGenericType(typeArgumentAttribute.Type);
            }
            else //require user to resolve generic arguments
            {
                ActivityTypeResolver wnd = new ActivityTypeResolver();
                if (null != context)
                {
                    WindowHelperService service = context.Services.GetService <WindowHelperService>();
                    if (null != service)
                    {
                        service.TrySetWindowOwner(dropTarget, wnd);
                    }
                }

                TypeResolvingOptions dropTargetOptions   = null;
                TypeResolvingOptions activityTypeOptions = null;

                //try to see if the container has any customization for type resolver
                ICompositeView container = dropTarget as ICompositeView;
                if (container != null)
                {
                    dropTargetOptions = container.DroppingTypeResolvingOptions;
                }

                //try to see if the activity type in discourse has any customization for type resolver
                TypeResolvingOptionsAttribute attr = WorkflowViewService.GetAttribute <TypeResolvingOptionsAttribute>(type);
                if (attr != null)
                {
                    activityTypeOptions = attr.TypeResolvingOptions;
                }
                //if both have type resolver, try to merge them
                TypeResolvingOptions options = TypeResolvingOptions.Merge(dropTargetOptions, activityTypeOptions);
                if (options != null)
                {
                    wnd.Options = options;
                }

                wnd.Context    = context;
                wnd.EditedType = type;
                wnd.Width      = 340;
                wnd.Height     = 200;
                type           = (true == wnd.ShowDialog() ? wnd.ConcreteType : null);
            }
            return(type);
        }
        // Get a path from the modelItem to the root.
        // Path is stored in pathStack as stack datastructure, itemSet is used to avoid loop.
        private static bool GetExpandingPath(ModelItem modelItem, Stack pathStack, HashSet <ModelItem> itemSet)
        {
            if (modelItem == null || itemSet.Contains(modelItem) || ExtensibilityAccessor.GetAttribute <HidePropertyInOutlineViewAttribute>(modelItem) != null)
            {
                return(false);
            }

            itemSet.Add(modelItem);
            pathStack.Push(modelItem);

            if (modelItem.Parents == null || modelItem.Parents.Count() == 0)
            {
                return(true);
            }

            if (modelItem.Sources != null && modelItem.Sources.Count() != 0)
            {
                // By design, modelItem's path to the parents is through Sources to their Parent.
                foreach (ModelProperty property in modelItem.Sources)
                {
                    // ModelProperties with HidePropertyInOutlineViewAttribute are also invisible.
                    if (ExtensibilityAccessor.GetAttribute <HidePropertyInOutlineViewAttribute>(property) == null)
                    {
                        // Property is also stored in the path stack because some properties have visible nodes in the designerTree.
                        pathStack.Push(property);
                        if (GetExpandingPath(property.Parent, pathStack, itemSet))
                        {
                            return(true);
                        }
                        else
                        {
                            pathStack.Pop();
                        }
                    }
                }
            }
            else
            {
                // If a modelItem is inside an modelItemCollection, its Sources property is null.
                foreach (ModelItem item in modelItem.Parents)
                {
                    if (GetExpandingPath(item, pathStack, itemSet))
                    {
                        return(true);
                    }
                }
            }

            itemSet.Remove(modelItem);
            pathStack.Pop();
            return(false);
        }
        internal static bool TryMorphExpression(ActivityWithResult originalExpression, bool isLocation, Type targetType,
                                                EditingContext context, out ActivityWithResult morphedExpression)
        {
            bool succeeded = false;

            morphedExpression = null;
            if (originalExpression != null)
            {
                Type resultType = originalExpression.ResultType;
                if ((isLocation) && (ExpressionHelper.IsGenericLocationExpressionType(originalExpression) && (targetType == resultType.GetGenericArguments()[0])) ||
                    (!isLocation) && (resultType == targetType))
                {
                    //no need to morph
                    succeeded         = true;
                    morphedExpression = originalExpression;
                }
                else
                {
                    Type expressionType = originalExpression.GetType();
                    if (expressionType.IsGenericType)
                    {
                        expressionType = expressionType.GetGenericTypeDefinition();
                    }

                    ExpressionMorphHelperAttribute morphHelperAttribute = ExtensibilityAccessor.GetAttribute <ExpressionMorphHelperAttribute>(expressionType);
                    if (morphHelperAttribute != null)
                    {
                        ExpressionMorphHelper morphHelper = Activator.CreateInstance(morphHelperAttribute.ExpressionMorphHelperType) as ExpressionMorphHelper;
                        if (morphHelper != null)
                        {
                            succeeded = morphHelper.TryMorphExpression(originalExpression, isLocation, targetType, context, out morphedExpression);
                            if (succeeded && morphedExpression != null)
                            {
                                string editorName = ExpressionActivityEditor.GetExpressionActivityEditor(originalExpression);
                                if (!string.IsNullOrWhiteSpace(editorName))
                                {
                                    ExpressionActivityEditor.SetExpressionActivityEditor(morphedExpression, editorName);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                succeeded = true;
            }
            return(succeeded);
        }
        internal override ChangeNotificationTracker GetTracker(ModelProperty modelProperty, bool createNew)
        {
            ChangeNotificationTracker tracker = base.GetTracker(modelProperty, createNew);

            if (createNew)
            {
                Fx.Assert(this.Value == modelProperty, "The modelProperty should be the same as this.Value.");
                tracker.Add(modelProperty.Parent, modelProperty);
                ShowInOutlineViewAttribute viewVisible = ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(modelProperty);
                if (viewVisible != null && !string.IsNullOrWhiteSpace(viewVisible.PromotedProperty))
                {
                    ModelProperty promotedProperty = modelProperty.Value.Properties.Find(viewVisible.PromotedProperty);
                    tracker.Add(promotedProperty.Parent, promotedProperty);
                }
            }

            return(tracker);
        }
Пример #8
0
        internal static void AddModelItemCollection(TreeViewItemViewModel parent, ModelItemCollection collection, ModelProperty trackingProperty)
        {
            parent.GetTracker(trackingProperty).AddCollection(collection);

            bool   duplicatedNodeVisible = true;
            string childNodePrefix       = string.Empty;
            ShowPropertyInOutlineViewAttribute viewChild = ExtensibilityAccessor.GetAttribute <ShowPropertyInOutlineViewAttribute>(trackingProperty);

            if (viewChild != null)
            {
                duplicatedNodeVisible = viewChild.DuplicatedChildNodesVisible;
                childNodePrefix       = viewChild.ChildNodePrefix;
            }

            foreach (ModelItem item in collection)
            {
                AddChild(parent, item, item, duplicatedNodeVisible, childNodePrefix, trackingProperty);
            }
        }
        // Enqueue Parents of given ModelItem
        // Do not enqueue source Properties with a ViewIgnore attribute
        private static void EnqueueParents(ModelItem item, Queue <ModelItem> queue)
        {
            Dictionary <ModelItem, int> nonSources = new Dictionary <ModelItem, int>();

            if (null != item)
            {
                // Initialize nonSources dictionary to hold all Parents
                foreach (ModelItem parent in item.Parents)
                {
                    if (nonSources.ContainsKey(parent))
                    {
                        ++nonSources[parent];
                    }
                    else
                    {
                        nonSources.Add(parent, 1);
                    }
                }

                // Enqueue Sources and remove found items from nonSources
                foreach (ModelProperty source in item.Sources)
                {
                    if (null != source.Parent)
                    {
                        if (null == ExtensibilityAccessor.GetAttribute <HidePropertyInOutlineViewAttribute>(source))
                        {
                            queue.Enqueue(source.Parent);
                        }

                        if (nonSources.ContainsKey(source.Parent))
                        {
                            --nonSources[source.Parent];
                        }
                    }
                }

                // Deal with the collections that contain this ModelItem
                foreach (KeyValuePair <ModelItem, int> kvp in nonSources.Where((kvp) => 0 < kvp.Value))
                {
                    queue.Enqueue(kvp.Key);
                }
            }
        }
Пример #10
0
        public TreeViewItemModelItemViewModel(TreeViewItemViewModel parent, ModelItem modelItem, bool lazyLoad)
            : base(parent)
        {
            this.Value = modelItem;
            ShowInOutlineViewAttribute attr = ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(modelItem);

            if (attr != null && !string.IsNullOrEmpty(attr.PromotedProperty))
            {
                // Only consider one level of promoted property.
                this.promotedProperty = modelItem.Properties[attr.PromotedProperty];
                if (this.promotedProperty != null)
                {
                    this.VisualValue = this.promotedProperty.Value;
                }
                else
                {
                    // is this what we really want?
                    Fx.Assert(attr.PromotedProperty + " not found on " + modelItem.Name);
                    this.VisualValue = null;
                }
            }
            else
            {
                this.VisualValue = modelItem;
            }

            IsHighlighted = Selection.IsSelection(this.VisualValue);

            if (lazyLoad)
            {
                this.UpdateState();
                if (this.HasChildren)
                {
                    this.InternalChildren.Add(TreeViewItemViewModel.DummyNode);
                }
            }
            else
            {
                this.LoadChildren();
            }
        }
Пример #11
0
        internal static void AddModelItemDictionary(TreeViewItemViewModel parent, ModelItemDictionary dictionary, ModelProperty trackingProperty)
        {
            parent.GetTracker(trackingProperty).AddCollection(dictionary);

            bool   duplicatedNodeVisible = true;
            string childNodePrefix       = string.Empty;
            ShowPropertyInOutlineViewAttribute viewChild = ExtensibilityAccessor.GetAttribute <ShowPropertyInOutlineViewAttribute>(trackingProperty);

            if (viewChild != null)
            {
                duplicatedNodeVisible = viewChild.DuplicatedChildNodesVisible;
                childNodePrefix       = viewChild.ChildNodePrefix;
            }

            foreach (var pair in dictionary)
            {
                ModelItem item = null;
                //AddChild(parent, pair.Value, pair, duplicatedNodeVisible, trackingProperty);
                AddChild(parent, item, pair, duplicatedNodeVisible, childNodePrefix, trackingProperty);
            }
        }
        // this method may has side effect, it may modify model.
        internal static bool TryInferReturnType(ActivityWithResult expression, EditingContext context, out Type returnType)
        {
            bool succeeded = false;

            returnType = null;
            Type expressionType = expression.GetType();

            if (expressionType.IsGenericType)
            {
                expressionType = expressionType.GetGenericTypeDefinition();
                ExpressionMorphHelperAttribute morphHelperAttribute = ExtensibilityAccessor.GetAttribute <ExpressionMorphHelperAttribute>(expressionType);
                if (morphHelperAttribute != null)
                {
                    ExpressionMorphHelper morphHelper = Activator.CreateInstance(morphHelperAttribute.ExpressionMorphHelperType) as ExpressionMorphHelper;
                    if (morphHelper != null)
                    {
                        succeeded = morphHelper.TryInferReturnType(expression, context, out returnType);
                    }
                }
            }
            return(succeeded);
        }
        // Return HashSet containing ModelItems found only through given property: Cannot reach property.Parent without
        // hitting property from these immediate descendents of property.Value
        // Set may contain some internal duplication -- all nodes, not just the root, of a linked tree will be included
        //
        // Caveat 1: Due to problems removing Parents (e.g. Case content sometimes holds references to FlowSwitch after
        // Case removed), this method is not entirely reliable -- customers may occasionally need to reopen Designer
        // Caveat 2: Due to lazy loading of Properties (and therefore the back-pointing Parents collection), may
        // temporarily include non-unique ModelItems in returned set -- cleared as tree or designer views expand
        //
        // (Throughout, cannot use ModelItem.GetParentEnumerator because that does not check all Sources and Parents)
        internal static HashSet <ModelItem> FindUniqueChildren(ModelProperty property)
        {
            HashSet <ModelItem> retval = new HashSet <ModelItem>();

            if (null != property && null != property.Parent && null != property.Value)
            {
                ModelItem           target   = property.Parent;
                ModelItem           expected = property.Value;
                HashSet <ModelItem> visited  = new HashSet <ModelItem>();

                // Check all immediate children of property.Value
                ModelItemCollection collection = expected as ModelItemCollection;
                if (null == collection)
                {
                    ModelItemDictionary dictionary = expected as ModelItemDictionary;
                    if (null == dictionary)
                    {
                        // ModelItem
                        // Can't use UniqueRoute because we're starting at expected
                        // Can't use EnqueueParents because we need to special-case given property
                        // Instead confirm property.Value is not referenced anywhere else
                        ModelItemImpl expectedImpl = expected as ModelItemImpl;
                        if (null != expectedImpl)
                        {
                            bool justThisSource = true;

                            // expectedImpl.InternalParents does not include ModelItems that are just Sources
                            if (0 == expectedImpl.InternalParents.Count)
                            {
                                // expectedImpl.InternalSources would be similar but adds a wrapper we don't need here
                                foreach (ModelProperty source in expected.Sources)
                                {
                                    if (null != source.Parent && !visited.Contains(source.Parent))
                                    {
                                        visited.Add(source.Parent);
                                        if (!property.Equals(source) && !expected.Equals(source) &&
                                            null == ExtensibilityAccessor.GetAttribute <HidePropertyInOutlineViewAttribute>(source))
                                        {
                                            // Found a non-ignored property from somewhere else referencing expected
                                            justThisSource = false;
                                            break;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                // Found a Parent that's not a Source.Parent: property.Value is in some collection
                                justThisSource = false;
                            }

                            if (justThisSource)
                            {
                                retval.Add(expected);
                            }
                        }
                    }
                    else
                    {
                        // ModelItemDictionary
                        foreach (KeyValuePair <ModelItem, ModelItem> child in dictionary)
                        {
                            if (null != child.Key && !visited.Contains(child.Key))
                            {
                                visited.Add(child.Key);
                                if (UniqueModelItemHelper.UniqueRoute(child.Key, target, expected))
                                {
                                    retval.Add(child.Key);
                                }
                            }

                            if (null != child.Value && !visited.Contains(child.Value))
                            {
                                visited.Add(child.Value);
                                if (UniqueModelItemHelper.UniqueRoute(child.Value, target, expected))
                                {
                                    retval.Add(child.Value);
                                }
                            }
                        }
                    }
                }
                else
                {
                    // ModelItemCollection
                    foreach (ModelItem child in collection)
                    {
                        if (null != child && !visited.Contains(child))
                        {
                            visited.Add(child);
                            if (UniqueModelItemHelper.UniqueRoute(child, target, expected))
                            {
                                retval.Add(child);
                            }
                        }
                    }
                }
            }

            return(retval);
        }
Пример #14
0
        internal static void AddModelProperty(TreeViewItemViewModel parent, ModelItem item, ModelProperty trackingProperty, ModelProperty property)
        {
            //in the case of multiple attributes, they go in this order
            //HidePropertyInOutlineViewAttribute
            //[item.ShowInOutlineViewAttribute.PromotedProperty = property.Name]. Set VisualValue by property and ignore itself. Usage ActivityDelegate, FlowStep.
            //ShowPropertyInOutlineViewAttribute
            //ShowPropertyInOutlineViewAsSiblingAttribute
            //ShowInOutlineViewAttribute
            ShowPropertyInOutlineViewAttribute viewChild = ExtensibilityAccessor.GetAttribute <ShowPropertyInOutlineViewAttribute>(property);

            if (ExtensibilityAccessor.GetAttribute <HidePropertyInOutlineViewAttribute>(property) != null)
            {
                //ignore
                return;
            }
            else if (IsPromotedProperty(item, property))
            {
                if (property.IsCollection)
                {
                    ModelItemCollection mc = property.Value as ModelItemCollection;
                    AddModelItemCollection(parent, mc, trackingProperty);
                }
                else if (property.IsDictionary)
                {
                    ModelItemDictionary dictionary = property.Dictionary;
                    AddModelItemDictionary(parent, dictionary, trackingProperty);
                }
                else
                {
                    parent.GetTracker(trackingProperty).Add(item, property);

                    //if property.Value is null, then this would not add any node
                    // Use promoted ModelItem's property to track, so pass null to AddModelItem method.
                    AddModelItem(parent, property.Value, null);
                }
            }
            else if (viewChild != null)
            {
                if (viewChild.CurrentPropertyVisible) //property node visible
                {
                    if (property.Value != null)
                    {
                        TreeViewItemViewModel childModel = TreeViewItemViewModel.CreateViewModel(parent, property);
                        childModel.DuplicatedNodeVisible = viewChild.DuplicatedChildNodesVisible;
                        parent.AddChild(childModel, trackingProperty);
                    }
                    else
                    {
                        //just add the notification tracker without adding the empty child
                        parent.GetTracker(trackingProperty, true).Add(item, trackingProperty);
                    }
                }
                else
                {
                    if (property.IsCollection)
                    {
                        ModelItemCollection mc = property.Value as ModelItemCollection;
                        AddModelItemCollection(parent, mc, trackingProperty);
                    }
                    else if (property.IsDictionary)
                    {
                        ModelItemDictionary dictionary = property.Dictionary;
                        AddModelItemDictionary(parent, dictionary, trackingProperty);
                    }
                    else
                    {
                        if (property.Value != null)
                        {
                            TreeViewItemViewModel childModel = TreeViewItemViewModel.CreateViewModel(parent, property.Value);
                            childModel.DuplicatedNodeVisible = viewChild.DuplicatedChildNodesVisible;
                            parent.AddChild(childModel, trackingProperty);
                        }
                        else
                        {
                            parent.GetTracker(trackingProperty).Add(item, property);
                        }
                    }
                }
            }
            else if (ExtensibilityAccessor.GetAttribute <ShowPropertyInOutlineViewAsSiblingAttribute>(property) != null)
            {
                //add notification to the tracker that is responsible for this node
                ChangeNotificationTracker tracker = parent.Parent.GetTracker(parent);
                tracker.Add(item, property);
                TreeViewItemViewModel siblingNode = null;
                if (property.Value != null)
                {
                    siblingNode = TreeViewItemViewModel.CreateViewModel(parent.Parent, property.Value);
                }
                parent.Parent.AddChild(siblingNode, tracker.ParentProperty);
            }
            else if (ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(property) != null)
            {
                if (property.Value != null)
                {
                    ShowInOutlineViewAttribute outlineView = ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(property);
                    if (string.IsNullOrWhiteSpace(outlineView.PromotedProperty))
                    {
                        parent.AddChild(TreeViewItemViewModel.CreateViewModel(parent, property), trackingProperty);
                    }
                    else
                    {
                        ModelProperty promotedProperty = property.Value.Properties.Find(outlineView.PromotedProperty);
                        if (promotedProperty == null)
                        {
                            throw FxTrace.Exception.AsError(new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, SR.PromotedPropertyNotFound, outlineView.PromotedProperty, property.Value.Name)));
                        }

                        // Add promoted ModelItem and property into tracker. So when property got changed, the grandparent of promoted ModelItem will be notified.
                        ChangeNotificationTracker tracker = parent.GetTracker(trackingProperty, true);
                        tracker.Add(property.Value, promotedProperty);

                        if (promotedProperty.Value == null)
                        {
                            tracker.Add(item, property);
                        }
                        else
                        {
                            parent.AddChild(TreeViewItemViewModel.CreateViewModel(parent, property), trackingProperty);
                        }
                    }
                }
                else
                {
                    parent.GetTracker(trackingProperty, true).Add(item, property);
                }
            }
            //if the values in the dictionary is viewvisible, note this only works with generic dictionary
            else if (property.IsDictionary && property.PropertyType.IsGenericType)
            {
                Type[] arguments = property.PropertyType.GetGenericArguments();
                if (ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(arguments[1]) != null)
                {
                    if (property.Value != null)
                    {
                        parent.AddChild(TreeViewItemViewModel.CreateViewModel(parent, property), trackingProperty);
                    }
                    else
                    {
                        parent.GetTracker(trackingProperty, true).Add(item, property);
                    }
                }
            }
        }
Пример #15
0
        IList <string> GetSearchableStrings(object computedValue)
        {
            List <string> results = new List <string>();

            if (computedValue == null || this.objectsOnDesinger.Contains(computedValue))
            {
                return(results);
            }

            Type type = computedValue.GetType();

            if (type.IsPrimitive || computedValue is string || type.IsEnum || computedValue is Uri)
            {
                return(new List <string>()
                {
                    computedValue.ToString()
                });
            }

            SearchableStringConverterAttribute attribute =
                ExtensibilityAccessor.GetAttribute <SearchableStringConverterAttribute>(type);

            if (attribute == null)
            {
                // try its generic type.
                if (type.IsGenericType)
                {
                    Type generictype = type.GetGenericTypeDefinition();
                    attribute = ExtensibilityAccessor.GetAttribute <SearchableStringConverterAttribute>(generictype);
                }
            }

            if (attribute != null)
            {
                Type converterType = Type.GetType(attribute.ConverterTypeName);
                if (converterType.IsGenericTypeDefinition)
                {
                    converterType = converterType.MakeGenericType(computedValue.GetType().GetGenericArguments());
                }
                SearchableStringConverter converter = Activator.CreateInstance(converterType) as SearchableStringConverter;
                return(converter.Convert(computedValue));
            }

            // don't have an direct converter? and is a collection, then let's try convert each member.
            if (computedValue is IEnumerable)
            {
                foreach (object value in computedValue as IEnumerable)
                {
                    results.AddRange(GetSearchableStrings(value));
                }
                return(results);
            }

            // Already tried all the options, let's do a recursive search.
            alreadyVisitedObjects.Add(computedValue);
            PropertyInfo[] properties = type.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                object propertyValue = property.GetValue(computedValue, null);
                if (!alreadyVisitedObjects.Contains(propertyValue))
                {
                    results.AddRange(GetSearchableStrings(propertyValue));
                }
            }
            return(results);
        }
 bool IsFlagsProperty(PropertyEntry property)
 {
     return(property != null && property.PropertyType != null && property.PropertyType.IsEnum &&
            ExtensibilityAccessor.GetAttribute <FlagsAttribute>(property.PropertyType) != null);
 }
        static bool CanCopyProperty(ModelProperty modelProperty, ModelProperty propertyInNewModelItem)
        {
            bool canCopyProperty = false;
            DesignerSerializationVisibilityAttribute designerSerializationVisibility = ExtensibilityAccessor.GetAttribute <DesignerSerializationVisibilityAttribute>(modelProperty.Attributes);

            if (modelProperty.Value == null)
            {
                canCopyProperty = false;
            }
            else if (designerSerializationVisibility != null && designerSerializationVisibility.Visibility != DesignerSerializationVisibility.Visible)
            {
                canCopyProperty = false;
            }
            else if (propertyInNewModelItem != null && !propertyInNewModelItem.IsAttached && !propertyInNewModelItem.IsReadOnly)
            {
                canCopyProperty = true;
            }
            return(canCopyProperty);
        }
Пример #18
0
        private TreeViewItemState UpdateModelItemState(ModelItem modelItem)
        {
            TreeViewItemState state = TreeViewItemState.Default;

            foreach (ModelProperty property in modelItem.Properties)
            {
                if (ExtensibilityAccessor.GetAttribute <HidePropertyInOutlineViewAttribute>(property) != null)
                {
                    continue;
                }
                else if (ExtensibilityAccessor.GetAttribute <ShowPropertyInOutlineViewAttribute>(property) != null)
                {
                    if (property.Value != null)
                    {
                        state |= TreeViewItemState.HasChildren;
                    }

                    // create the property change notification tracker
                    this.GetTracker(property, true);
                }
                else if (ExtensibilityAccessor.GetAttribute <ShowPropertyInOutlineViewAsSiblingAttribute>(property) != null)
                {
                    // First of all, ShowPropertyInOutlineViewAsSiblingAttribute property's tracker will be setup at the LoadChildren() time.
                    // The reason we cannot do it here is because during the constructor, this.Parent is null.
                    // If all other properties don't flag HasChildren, the current node won't be able to expand.
                    // So we cannot rely on expand operation to invoke LoadChildren() to setup tracker.
                    // TreeViewItemViewModel.AddChild(TreeViewItemViewModel, ModelProperty) will by default invoke LoadChildren() if the node HasSibling.
                    // So even if property's value == null, we should flag it HasSibling, and let LoadChildren invoked by default.
                    state |= TreeViewItemState.HasSibling;
                }
                else if (ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(property) != null)
                {
                    if (property.Value != null)
                    {
                        // Only consider one level of PromotedProperty.
                        if (property != this.promotedProperty)
                        {
                            state |= TreeViewItemState.HasChildren;
                        }
                        else
                        {
                            // Since the property has been promoted, need to check whether this property has children.
                            // If this promoted property.Value has children, those children should belong to this node.
                            state |= this.UpdateModelItemState(property.Value);
                        }
                    }

                    this.GetTracker(property, true);
                }
                else if (property.IsDictionary && property.PropertyType.IsGenericType)
                {
                    // if the values in the dictionary is viewvisible, note this only works with generic dictionary
                    Type[] arguments = property.PropertyType.GetGenericArguments();
                    if (ExtensibilityAccessor.GetAttribute <ShowInOutlineViewAttribute>(arguments[1]) != null)
                    {
                        if (property.Value != null)
                        {
                            state |= TreeViewItemState.HasChildren;
                        }

                        this.GetTracker(property, true);
                    }
                }
            }

            return(state);
        }
Пример #19
0
        private DrawingBrush GetIconByVisualValue()
        {
            if (this.VisualValue != null)
            {
                DrawingBrush icon          = null;
                Type         modelItemType = this.VisualValue.ItemType;
                if (modelItemType.IsGenericType)
                {
                    // If Type is generic type, whatever T, it should display same icon, so use generic type instead.
                    modelItemType = this.VisualValue.ItemType.GetGenericTypeDefinition();
                }

                // If the user specifies the attribute, then the Designer would be providing the icon,
                // bypassing the pipeline of retrieving the icons via reflection and attached properties.
                ActivityDesignerOptionsAttribute attr = ExtensibilityAccessor.GetAttribute <ActivityDesignerOptionsAttribute>(modelItemType);
                if (attr != null && attr.OutlineViewIconProvider != null)
                {
                    icon = attr.OutlineViewIconProvider(this.VisualValue);
                }

                if (icon == null && !TreeViewItemViewModel.IconCache.TryGetValue(modelItemType, out icon))
                {
                    EditingContext      context             = this.VisualValue.GetEditingContext();
                    ViewService         service             = context.Services.GetService <ViewService>();
                    WorkflowViewService workflowViewService = service as WorkflowViewService;
                    ActivityDesigner    designer            = null;

                    // first try to create an detached view element that won't participate in the designer,
                    // if the view service is WorkflowViewService
                    if (workflowViewService != null)
                    {
                        designer = workflowViewService.CreateDetachedViewElement(this.VisualValue) as ActivityDesigner;
                        icon     = GetIconFromUnInitializedDesigner(designer);
                    }
                    else
                    {
                        // fall back if the view service is not the default implementation
                        // We only need to get the icon from the designer, so we don't need to make sure the view is parented.
                        designer = this.VisualValue.View as ActivityDesigner;
                        if (designer == null && service != null)
                        {
                            designer = service.GetView(this.VisualValue) as ActivityDesigner;
                        }

                        if (designer != null)
                        {
                            if (designer.Icon != null || designer.IsLoaded)
                            {
                                icon = designer.Icon;
                            }
                            else
                            {
                                icon = GetIconFromUnInitializedDesigner(designer);
                            }
                        }
                    }

                    // Cache even a null icon since answers found above won't change within this AppDomain
                    TreeViewItemViewModel.IconCache.Add(modelItemType, icon);
                }

                return(icon);
            }
            else
            {
                return(null);
            }
        }