// <summary>
        // Gets the underlying ModelItemCollection
        // </summary>
        // <returns>The underlying ModelItemCollection</returns>
        internal ModelItemCollection GetRawCollection()
        {
            ModelPropertyEntry parentAsEntry = ParentValue.ParentProperty as ModelPropertyEntry;

            if (parentAsEntry != null)
            {
                return(parentAsEntry.FirstModelProperty.Collection);
            }

            ModelPropertyIndexer parentAsIndexer = ParentValue.ParentProperty as ModelPropertyIndexer;

            if (parentAsIndexer != null)
            {
                ModelItemCollection modelItemCollection = parentAsIndexer.ModelItem as ModelItemCollection;

                // If the parent is an indexer, that means we are a collection within another collection
                // and the ModelItem of the indexer is really a ModelItemCollection.
                Fx.Assert(modelItemCollection != null, "modelItemCollection should not be null");

                return(modelItemCollection);
            }

            Debug.Fail("A new class was introduced that derives from PropertyEntry.  Need to update ModelPropertyValueCollection code as well.");
            return(null);
        }
Exemplo n.º 2
0
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string result = null;

            if (value != null)
            {
                ModelPropertyEntry modelPropertyEntry = value as ModelPropertyEntry;
                if (modelPropertyEntry != null)
                {
                    StringBuilder propertyPath = new StringBuilder(modelPropertyEntry.PropertyName);
                    propertyPath.Insert(0, '.');

                    ModelProperty property = modelPropertyEntry.FirstModelProperty;
                    if (property != null)
                    {
                        ModelItem convertedValue = property.Parent;
                        while (convertedValue != null && !typeof(Activity).IsAssignableFrom(convertedValue.ItemType))
                        {
                            if (null != convertedValue.Source)
                            {
                                propertyPath.Insert(0, convertedValue.Source.Name);
                                propertyPath.Insert(0, '.');
                            }
                            convertedValue = convertedValue.Parent;
                        }
                    }
                    propertyPath.Remove(0, 1);
                    result = propertyPath.ToString();
                }
            }
            return(result);
        }
        internal static ModelItem Convert(ModelPropertyEntry modelPropertyEntry, bool returnParentActivity)
        {
            ModelItem convertedValue = null;

            if (modelPropertyEntry != null)
            {
                ModelProperty property = modelPropertyEntry.FirstModelProperty;
                if (property != null)
                {
                    convertedValue = property.Parent;
                    if (returnParentActivity)
                    {
                        while (convertedValue != null)
                        {
                            Type itemType = convertedValue.ItemType;
                            if (typeof(Activity).IsAssignableFrom(itemType) || typeof(WorkflowService).IsAssignableFrom(itemType))
                            {
                                break;
                            }

                            convertedValue = convertedValue.Parent;
                        }
                    }
                }
            }

            return(convertedValue);
        }
Exemplo n.º 4
0
        private static int CompareCore(object x, object y)
        {
            ModelPropertyEntry j = x as ModelPropertyEntry;
            ModelPropertyEntry k = y as ModelPropertyEntry;

            if (j == null && k == null)
            {
                return(0);
            }
            if (j == null)
            {
                return(-1);
            }
            if (k == null)
            {
                return(1);
            }

            PropertyOrder a = j.PropertyOrder ?? DefaultOrder;
            PropertyOrder b = k.PropertyOrder ?? DefaultOrder;

            int result = a.CompareTo(b);

            return(result != 0 ? result : string.Compare(j.DisplayName, k.DisplayName, StringComparison.CurrentCulture));
        }
        // <summary>
        // Basic ctor
        // </summary>
        // <param name="property">Property to display</param>
        // <param name="valueDialogTemplate">Template to use</param>
        public PropertyValueDialogControl(PropertyEntry property, DataTemplate valueDialogTemplate)
        {
            Fx.Assert(property != null, "property parameter is null");
            Fx.Assert(valueDialogTemplate != null, "valueDialogTemplate parameter is null");

            ModelPropertyEntry modelPropertyValue = property as ModelPropertyEntry;

            if (modelPropertyValue != null)
            {
                _rootTransaction = modelPropertyValue.FirstModelProperty.Value.BeginEdit();
            }

            InitializeComponent();

            // Make sure we use PI-specific resources within this control
            this.Resources.MergedDictionaries.Add(PropertyInspectorResources.GetResources());

            // Hook into an opening of nested dialogs.  PropertyInspector class takes care of this for us.
            // However, we are using Blend's collection editor which doesn't do the same thing, so
            // we need to reproduce that behavior manually.
            PropertyValueDialogHost.AttachOpenDialogHandlers(this);

            // Hook into the standard set of Commands
            _defaultCommandHandler = new PropertyValueEditorCommandHandler(this);


            _OKButton.Click                += new RoutedEventHandler(OnOkButtonClicked);
            _cancelButton.Click            += new RoutedEventHandler(OnCancelButtonClicked);
            _contentControl.Content         = property.PropertyValue;
            _contentControl.ContentTemplate = valueDialogTemplate;

            //Handle the commit and cancel keys within the property inspector, that is hosted in the collection editor
            ValueEditorUtils.SetHandlesCommitKeys(this, true);
        }
Exemplo n.º 6
0
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            FlowDirection returnValue = FlowDirection.LeftToRight;

            Fx.Assert(values.Length == 3, "Incorrect values in the MultiValueConverter!");
            if (values.Length == 3)
            {
                ModelPropertyEntry propertyEntry = values[1] as ModelPropertyEntry;
                if (propertyEntry != null)
                {
                    if (!propertyEntry.DisplayName.Equals("Name"))
                    {
                        if (targetType == typeof(FlowDirection))
                        {
                            object propertyValue = values[0];
                            if (propertyValue == null || propertyValue.GetType() == typeof(string))
                            {
                                //customize it to controls FlowDirection Property
                                returnValue = (FlowDirection)PropertyInspectorResources.GetResources()["SelectedControlFlowDirectionRTL"];
                            }
                        }
                    }
                }
            }
            return(returnValue);
        }
Exemplo n.º 7
0
        // ShowCategoryHeader DP

        // In Cider and unlike in Blend, we expose all properties (browsable and non-browsable) through the
        // property editing object model.  Hence, we need to make sure that the UI representing it (CategoryContainer)
        // does the filtering instead.  This is by design and, for consistency, it should be pushed into Blend as well
        protected override void AddProperty(PropertyEntry property, ObservableCollection <PropertyEntry> unconsumedProperties, ObservableCollection <PropertyEntry> referenceOrder, ObservableCollection <CategoryEditor> categoryEditors)
        {
            // Is this property browsable?
            ModelPropertyEntry modelPropertyEntry = property as ModelPropertyEntry;

            if (modelPropertyEntry != null && !modelPropertyEntry.IsBrowsable)
            {
                return;
            }

            // Yes, so we can safely add it to the list
            base.AddProperty(property, unconsumedProperties, referenceOrder, categoryEditors);
        }
Exemplo n.º 8
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);
        }
Exemplo n.º 9
0
        private static bool CullDisassociatedProperties(ObservableCollectionWorkaround <PropertyEntry> propertyList)
        {
            bool propertiesCulled = false;

            for (int i = propertyList.Count - 1; i >= 0; i--)
            {
                ModelPropertyEntry property = (ModelPropertyEntry)propertyList[i];
                if (property.Disassociated)
                {
                    property.Disconnect();
                    propertyList.RemoveAt(i);
                    propertiesCulled = true;
                }
            }

            return(propertiesCulled);
        }
Exemplo n.º 10
0
        // Another Blend work-around - we expose all properties through the OM, not just the
        // Browsable ones.  However, as a result, we need to cull the non-browsable ones from
        // consideration.  Otherwise, empty categories may appear.
        protected override bool DoesPropertyMatchFilter(PropertyFilter filter, PropertyEntry property)
        {
            property.ApplyFilter(filter);

            bool isBrowsable = true;
            ModelPropertyEntry modelPropertyEntry = property as ModelPropertyEntry;

            if (modelPropertyEntry != null)
            {
                //display given property if it is browsable or
                isBrowsable = modelPropertyEntry.IsBrowsable ||
                              // it may not be browsable, but if there is a category editor associated - display it anyway
                              (this.CategoryEditors != null && this.CategoryEditors.Count != 0);
            }

            return(isBrowsable && property.MatchesFilter);
        }
Exemplo n.º 11
0
        private void CreateCollection(ModelPropertyEntry parentProperty)
        {
            // Assert some assumptions that should be true at this point
            Fx.Assert(parentProperty != null, "parentProperty should not be null");
            Fx.Assert(parentProperty.ModelPropertySet != null, "parentProperty.ModelPropertySet should not be null");
            Fx.Assert(parentProperty.ModelPropertySet.Count > 0, "parentProperty.ModelPropertySet.Count should be > 0");

            // Ignore sub-properties of MarkupExtensions for v1
            if (parentProperty.IsMarkupExtension)
            {
                return;
            }

            IEnumerable <IList <ModelProperty> > mergedSubProperties = ModelPropertyMerger.GetMergedSubProperties(parentProperty.ModelPropertySet);

            int  index       = 0;
            bool multiSelect = parentProperty.ModelPropertySet.Count > 1;

            foreach (IList <ModelProperty> subPropertySet in mergedSubProperties)
            {
                if (index == 0)
                {
                    _properties = new List <ModelPropertyEntry>();
                }

                ModelPropertyEntry entry;

                if (multiSelect)
                {
                    entry = new ModelPropertyEntry(subPropertySet, (ModelPropertyValue)parentProperty.PropertyValue);
                }
                else
                {
                    entry = new ModelPropertyEntry(subPropertySet[0], (ModelPropertyValue)parentProperty.PropertyValue);
                }

                _properties.Add(entry);
                index++;
            }

            // Sort the sub-properties by their OrderToken as well as their name
            if (_properties != null)
            {
                _properties.Sort();
            }
        }
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            ModelItem convertedValue = null;

            if (values[1] != null)
            {
                ModelPropertyEntry modelPropertyEntry = values[1] as ModelPropertyEntry;
                if (modelPropertyEntry != null)
                {
                    ModelProperty property = modelPropertyEntry.FirstModelProperty;
                    if (property != null)
                    {
                        convertedValue = property.Value;
                    }
                }
            }
            return(convertedValue);
        }
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            PropertyEntry propertyEntry = value as PropertyEntry;

            if (null == propertyEntry)
            {
                PropertyValue propertyValue = value as PropertyValue;
                if (null != propertyValue)
                {
                    propertyEntry = propertyValue.ParentProperty;
                }
            }

            ModelPropertyEntry modelPropertyEntry = propertyEntry as ModelPropertyEntry;

            ModelProperty modelProperty = null;

            if (modelPropertyEntry != null)
            {
                modelProperty = modelPropertyEntry.FirstModelProperty;
            }

            if (modelProperty == null)
            {
                return(Binding.DoNothing);
            }

            string optionName = parameter as string;

            if (optionName == null)
            {
                return(Binding.DoNothing);
            }

            object optionValue;

            if (EditorOptionAttribute.TryGetOptionValue(modelProperty.Attributes, optionName, out optionValue))
            {
                return(optionValue);
            }

            return(Binding.DoNothing);
        }
Exemplo n.º 14
0
        private static int CompareCore(object x, object y)
        {
            ModelPropertyEntry j = x as ModelPropertyEntry;
            ModelPropertyEntry k = y as ModelPropertyEntry;

            if (j == null && k == null)
            {
                return(0);
            }
            if (j == null)
            {
                return(-1);
            }
            if (k == null)
            {
                return(1);
            }

            return(string.Compare(j.DisplayName, k.DisplayName, StringComparison.CurrentCulture));
        }
Exemplo n.º 15
0
        // <summary>
        // Removes and re-adds the specified property from this category, if it existed
        // there to begin with.  Noop otherwise.
        //
        // Use this method to refresh the cate----zation of a property if it suddenly
        // becomes Advanced if it was Basic before, or if its IsBrowsable status changes.
        // </summary>
        // <param name="property">Property to refresh</param>
        // <param name="bucket">Property bucket to repopulate</param>
        // <param name="sortComparer">Comparer to use to reinsert the given property in its new place</param>
        internal void Refresh(ModelPropertyEntry property, ObservableCollection <PropertyEntry> bucket, IComparer <PropertyEntry> sortComparer)
        {
            if (property == null)
            {
                throw FxTrace.Exception.ArgumentNull("property");
            }
            if (bucket != _basicProperties && bucket != _advancedProperties)
            {
                Debug.Fail("Invalid bucket specified.  Property was not refreshed.");
                return;
            }

            // Let's see if we know about this property
            ObservableCollectionWorkaround <PropertyEntry> collection;

            collection = _advancedProperties;

            int index = collection.BinarySearch(property, null);

            if (index < 0)
            {
                collection = _basicProperties;
                index      = collection.BinarySearch(property, null);
            }

            // If not, noop
            if (index < 0)
            {
                return;
            }

            // We know about this property, so refresh it.  It may have changed
            // somehow (eg. switched from basic to advanced, become hidden, etc.)
            // so make sure it's thrown into the right bucket.
            collection.RemoveAt(index);
            Add(property, bucket, sortComparer, false);
        }
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            ModelItem convertedValue = null;

            if (values[1] != null)
            {
                ModelPropertyEntry modelPropertyEntry = values[1] as ModelPropertyEntry;
                if (modelPropertyEntry != null)
                {
                    ModelProperty property = modelPropertyEntry.FirstModelProperty;
                    if (property != null)
                    {
                        ModelItem argumentModelItem = property.Value;
                        if (argumentModelItem != null &&
                            argumentModelItem.Properties["Expression"] != null &&
                            argumentModelItem.Properties["Expression"].Value != null)
                        {
                            convertedValue = argumentModelItem.Properties["Expression"].Value;
                        }
                    }
                }
            }
            return(convertedValue);
        }
Exemplo n.º 17
0
        // This is the work-horse that refreshes the list of properties and categories within a PropertyInspector
        // window, including refreshing of CategoryEditors, based on the specified selection
        private void UpdateCategories(View.Selection selection, bool attachedOnly)
        {
            // Optimization stolen from Sparkle:
            // re-rendering the categories is the number one perf issue. Clearing
            // the databound collection results in massive Avalon code execution, and
            // then re-adding everything causes another huge shuffle. What is more,
            // even when changing the selection between different objects, most properties
            // do not change. Therefore we are going to take the new list of properties
            // and we are going to merge them into the existing stuff, using an
            // approach I call Mark, Match, and Cull.
            //
            // First we mark all the properties in the current collection. Those which
            // are still marked at the end will be culled out
            foreach (ModelCategoryEntry category in _categoryList)
            {
                if (attachedOnly)
                {
                    category.MarkAttachedPropertiesDisassociated();
                }
                else
                {
                    category.MarkAllPropertiesDisassociated();
                }
            }

            // Second we try to match each property in the list of properties for the newly selected objects
            // against something that we already have. If we have a match, then we reset the existing
            // ModelPropertyEntry and clear the mark
            //
            foreach (IEnumerable <ModelProperty> propertySet in
                     ModelPropertyMerger.GetMergedProperties(
                         selection == null ? null : selection.SelectedObjects,
                         selection == null ? 0 : selection.SelectionCount))
            {
                string propertyName = GetPropertyName(propertySet);

                // Specifically filter out the Name property
                // PS 40699 - Name is not a special property for WF
                //if ("Name".Equals(propertyName))
                //{
                //    continue;
                //}

                if (attachedOnly && propertyName.IndexOf('.') < 0)
                {
                    continue;
                }

                ModelPropertyEntry wrappedProperty = _propertyToolBar.CurrentViewManager.AddProperty(propertySet, propertyName, _categoryList);

                // Make sure no valid properties get culled out
                wrappedProperty.Disassociated = false;
            }

            // Third, we walk the properties and categories, and we cull out all of the
            // marked properties. Empty categories are removed.
            //
            for (int i = _categoryList.Count - 1; i >= 0; i--)
            {
                ModelCategoryEntry category = (ModelCategoryEntry)_categoryList[i];
                category.CullDisassociatedProperties();
                if (category.IsEmpty)
                {
                    _categoryList.RemoveAt(i);
                }
            }

            _categoryList.RefreshFilter();
        }
Exemplo n.º 18
0
        // <summary>
        // Same as GetSubPropertyHierarchyPath(), but it looks up a cached version
        // of this path, if one exists, or calculates one from scratch and caches it
        // if it doesn't.
        // </summary>
        // <param name="property">Property to get the name of</param>
        // <returns>',' separated property name for sub-properties</returns>
        public static string GetCachedSubPropertyHierarchyPath(PropertyEntry property)
        {
            ModelPropertyEntry mpe = property as ModelPropertyEntry;

            return(mpe == null?GetSubPropertyHierarchyPath(property) : mpe.SubPropertyHierarchyPath);
        }
Exemplo n.º 19
0
 // <summary>
 // Basic ctor
 // </summary>
 // <param name="parentProperty">Parent property</param>
 public ModelPropertyEntryCollection(ModelPropertyEntry parentProperty)
     : base(parentProperty.PropertyValue)
 {
     CreateCollection(parentProperty);
 }