Esempio n. 1
0
        // Parses the sub-properties of the given parent collection item and populates a corresponding
        // private list of ModelPropertyEntries that represents it.
        private void CreateCollection(ModelPropertyIndexer parentCollectionItem)
        {
            // Assert some assumptions that should be true at this point
            Fx.Assert(parentCollectionItem.ModelItem != null, "parentCollectionItem.ModelItem should not be null");

            List <ModelProperty> subProperties = ExtensibilityAccessor.GetSubProperties(parentCollectionItem.ModelItem);

            if (subProperties == null || subProperties.Count < 1)
            {
                return;
            }

            // At this point we have at least one ModelProperty that acts as a subProperty of the
            // given ModelItem.  Wrap the list in ModelPropertyEntries and exit.

            _properties = new List <ModelPropertyEntry>(subProperties.Count);

            for (int i = 0; i < subProperties.Count; i++)
            {
                _properties.Add(new ModelPropertyEntry(subProperties[i], (ModelPropertyValue)parentCollectionItem.PropertyValue));
            }

            // Sort the sub-properties by their OrderToken as well as their name
            if (_properties != null)
            {
                _properties.Sort();
            }
        }
        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);
        }
        // <summary>
        // Finds the consolidated default property name and returns it.  If there is no shared
        // default property betweem the specified items, null is returned.
        // </summary>
        // <param name="items">Items to examine</param>
        // <returns>Shared default property, if any.</returns>
        public static string GetMergedDefaultProperty(IEnumerable <ModelItem> items)
        {
            if (items == null)
            {
                return(null);
            }

            bool   firstIteration        = true;
            string mergedDefaultProperty = null;

            foreach (ModelItem item in items)
            {
                string currentDefaultProperty = ExtensibilityAccessor.GetDefaultProperty(item.ItemType);

                if (firstIteration)
                {
                    mergedDefaultProperty = currentDefaultProperty;
                }
                else if (!string.Equals(currentDefaultProperty, mergedDefaultProperty))
                {
                    mergedDefaultProperty = null;
                }

                if (string.IsNullOrEmpty(mergedDefaultProperty))
                {
                    return(null);
                }

                firstIteration = false;
            }

            return(mergedDefaultProperty);
        }
Esempio n. 4
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);
        }
Esempio n. 5
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);
        }
            public override IEnumerator <IEnumerable <ModelProperty> > GetEnumerator()
            {
                if (_parentProperties == null)
                {
                    yield break;
                }

                foreach (ModelProperty property in _parentProperties)
                {
                    yield return(ExtensibilityAccessor.GetSubProperties(property));
                }
            }
        void AddEntriesForProperty(ModelProperty property, ModelItem modelItem, string propertyPath)
        {
            if (!string.IsNullOrEmpty(propertyPath))
            {
                propertyPath += ",";
                propertyPath += property.Name;
            }
            else
            {
                propertyPath = property.Name;
            }

            entries.Add(CreateSearchableEntry(
                            SearchableEntryOption.Property, modelItem, property, TypeNameHelper.GetDisplayName(property.PropertyType, false), propertyPath));

            entries.Add(CreateSearchableEntry(
                            SearchableEntryOption.Property, modelItem, property, property.Name, propertyPath));

            if (property.ComputedValue != null)
            {
                PropertyValueEditor propertyValueEditor = null;
                try
                {
                    propertyValueEditor = ExtensibilityAccessor.GetSubPropertyEditor(property);
                }
                catch (TargetInvocationException exception)
                {
                    // To workaround 181412.If the current property's property type is a generic type and the activity
                    // is also a generic type Calling to ExtensibilityAccessor.GetSubPropertyEditor will get this exception.
                    if (exception.InnerException is ArgumentException)
                    {
                        propertyValueEditor = null;
                    }
                }
                if (propertyValueEditor != null)
                {
                    IList <ModelProperty> properties = ExtensibilityAccessor.GetSubProperties(property);
                    foreach (ModelProperty propertyItem in properties)
                    {
                        AddEntriesForProperty(propertyItem, modelItem, propertyPath);
                    }
                }
                else
                {
                    // We don't search the value of an expandable property.
                    AddEntriesForPropertyValue(property.ComputedValue, modelItem, property, SearchableEntryOption.Property, propertyPath);
                }
            }
            else if (property.Reference != null)
            {
                AddEntriesForPropertyReference(property.Reference, modelItem, property, SearchableEntryOption.Property, propertyPath);
            }
        }
        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);
        }
Esempio n. 10
0
 // Adds any CategoryEditors associated with the specified type
 private static void AddTypeCategoryEditors(Dictionary <Type, object> categoryEditorSet, Type type)
 {
     if (type != null)
     {
         IEnumerable <Type> editorTypes = ExtensibilityAccessor.GetCategoryEditorTypes(type);
         if (editorTypes != null)
         {
             foreach (Type editorType in editorTypes)
             {
                 categoryEditorSet[editorType] = null;
             }
         }
     }
 }
        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);
        }
Esempio n. 12
0
        // IPropertyViewManager Members

        // <summary>
        // Add a property into the correct category within the specified CategoryList.
        // </summary>
        // <param name="propertySet">Specified property (passed in as a set for multi-select scenarios)</param>
        // <param name="propertyName">Name of the current property (perf optimization)</param>
        // <param name="categoryList">CategoryList instance to populate</param>
        // <returns>Wrapped ModelPropertyEntry for the specified propertySet</returns>
        public ModelPropertyEntry AddProperty(IEnumerable <ModelProperty> propertySet, string propertyName, CategoryList categoryList)
        {
            string             categoryName = GetCategoryName(propertySet);
            ModelCategoryEntry category     = categoryList.FindCategory(categoryName) as ModelCategoryEntry;

            bool reuseEntries = ExtensibilityAccessor.IsEditorReusable(propertySet);

            if (reuseEntries && category != null)
            {
                ModelPropertyEntry foundProperty;
                if ((foundProperty = (ModelPropertyEntry)category[propertyName]) != null)
                {
                    if (foundProperty.PropertyType != null && foundProperty.PropertyType.Equals(System.Activities.Presentation.Internal.PropertyEditing.Model.ModelUtilities.GetPropertyType(propertySet)))
                    {
                        // Found a match for the property, so reuse it

                        bool oldIsBrowsable = foundProperty.IsBrowsable;
                        bool oldIsAdvanced  = foundProperty.IsAdvanced;

                        foundProperty.SetUnderlyingModelProperty(propertySet);

                        // If the IsBrowsable or IsAdvanced value of the property changed,
                        // refresh the property within the category, because how and whether
                        // this property should be rendered may have changed.
                        // Note that refreshing a selected property also nullifies its stickiness
                        // (ie. it resets CategoryList.PropertySelectionMode)
                        if (oldIsAdvanced != foundProperty.IsAdvanced ||
                            oldIsBrowsable != foundProperty.IsBrowsable)
                        {
                            category.Refresh(foundProperty, category.GetBucket(foundProperty), this.PropertyComparer);
                        }

                        return(foundProperty);
                    }
                }
            }

            if (category == null)
            {
                category = new ModelCategoryEntry(categoryName);
                categoryList.InsertAlphabetically(category);
            }

            ModelPropertyEntry property = new ModelPropertyEntry(propertySet, null);

            category.Add(property, category.GetBucket(property), this.PropertyComparer);
            return(property);
        }
Esempio n. 13
0
        private static string GetCategoryName(IEnumerable <ModelProperty> propertySet)
        {
            if (propertySet == null)
            {
                return(null);
            }

            // Note: ExtensibilityAccessor uses CategoryAttribute to look up the category name.
            // CategoryAttribute logic tries to look up the localized names for standard category names
            // by default already.  CategoryNameMap.GetLocalizedCategoryName() takes care of the few,
            // special WPF categories that are not found by the existing mechanism.
            foreach (ModelProperty property in propertySet)
            {
                return(CategoryNameMap.GetLocalizedCategoryName(ExtensibilityAccessor.GetCategoryName(property)));
            }
            return(null);
        }
        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);
        }
Esempio n. 15
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);
                }
            }
        }
Esempio n. 17
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();
            }
        }
Esempio n. 18
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);
        }
        public void InitializeFeature(Type modelType)
        {
            Fx.Assert(modelType != null, "Why would anyone initialize a feature that is not associated with a type");

            if (!initializedTypes.Contains(modelType))
            {
                initializedTypes.Add(modelType);
                foreach (FeatureAttribute featureAttribute in ExtensibilityAccessor.GetAttributes <FeatureAttribute>(modelType))
                {
                    if (typeof(Feature).IsAssignableFrom(featureAttribute.Type))
                    {
                        Feature feature = (Feature)Activator.CreateInstance(featureAttribute.Type);
                        if (feature != null)
                        {
                            feature.Initialize(this.context, modelType);
                        }
                    }
                }
                if (modelType.IsGenericType)
                {
                    InitializeFeature(modelType.GetGenericTypeDefinition());
                }
            }
        }
Esempio n. 21
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);
            }
        }
Esempio n. 22
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);
                    }
                }
            }
        }
Esempio n. 23
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);
 }
        // 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);
        }
        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);
        }
Esempio n. 27
0
        private void RefreshQuickTypes()
        {
            bool previousValue = IgnoreInternalChanges();

            try
            {
                _quickTypeCollection.Clear();

                PropertyEntry containedProperty = this.PropertyEntry;
                if (containedProperty == null)
                {
                    return;
                }

                ModelProperty           property             = ((ModelPropertyEntry)containedProperty).FirstModelProperty;
                Type                    containerValueType   = ((ModelPropertyEntryBase)containedProperty).CommonValueType;
                NewItemFactoryTypeModel selectedFactoryModel = null;
                Type                    defaultItemType      = GetDefaultItemType(property);

                // Find all elligible NewItemFactoryTypes declared through metadata
                IEnumerable <NewItemFactoryTypeModel> factoryModels =
                    ExtensibilityAccessor.GetNewItemFactoryTypeModels(
                        property,
                        ResourceUtilities.GetDesiredTypeIconSize(this));

                if (factoryModels != null)
                {
                    foreach (NewItemFactoryTypeModel factoryModel in factoryModels)
                    {
                        _quickTypeCollection.Add(factoryModel);

                        if (selectedFactoryModel == null)
                        {
                            if (object.Equals(containerValueType, factoryModel.Type))
                            {
                                selectedFactoryModel = factoryModel;
                            }
                        }

                        if (defaultItemType != null &&
                            object.Equals(defaultItemType, factoryModel.Type))
                        {
                            defaultItemType = null;
                        }
                    }
                }

                //add a null value - user should always have an option to clear property value
                NewItemFactoryTypeModel nullTypeFactoryTypeModel =
                    new NewItemFactoryTypeModel(null, new NullItemFactory());

                // Add a default item type based on the property type (if it wasn't also added through
                // metadata)
                if (defaultItemType != null)
                {
                    NewItemFactoryTypeModel defaultItemFactoryTypeModel = new NewItemFactoryTypeModel(defaultItemType, new NewItemFactory());
                    _quickTypeCollection.Add(defaultItemFactoryTypeModel);

                    if (selectedFactoryModel == null)
                    {
                        if (object.Equals(containerValueType, defaultItemFactoryTypeModel.Type))
                        {
                            selectedFactoryModel = defaultItemFactoryTypeModel;
                        }
                        else if (containerValueType == null)
                        {
                            selectedFactoryModel = nullTypeFactoryTypeModel;
                        }
                    }
                }

                _quickTypeCollection.Add(nullTypeFactoryTypeModel);

                // Make sure the currently selected value on the CollectionView reflects the
                // actual value of the property
                _quickTypeView.MoveCurrentTo(selectedFactoryModel);
                this.CurrentQuickType = selectedFactoryModel;
            }
            finally
            {
                NoticeInternalChanges(previousValue);
            }
        }
Esempio n. 28
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);
        }