1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //----------------------------------------------------------------
4 namespace System.Activities.Presentation.Internal.PropertyEditing.Model
7 using System.Collections;
8 using System.Collections.Generic;
9 using System.ComponentModel;
10 using System.Diagnostics;
13 using System.Activities.Presentation;
14 using System.Activities.Presentation.Model;
15 using System.Activities.Presentation.PropertyEditing;
16 using System.Activities.Presentation.Services;
19 // Cider-specific base class for PropertyEntry. It is shared by both
20 // ModelPropertyEntry and ModelPropertyIndexer. ModelPropertyEntry is used
21 // to model regular properties that are backed by Cider's ModelProperty.
22 // ModelPropertyIndexers are used to model items in collections that are
23 // backed by Cider's ModelItems.
25 internal abstract class ModelPropertyEntryBase : PropertyEntry
28 // Cache the depth of this property because once a property entry is create
29 // it doesn't jump levels. Depth is only used to track sub-property tree's
30 // not collection trees.
32 private string _propertyPath;
34 protected ModelPropertyEntryBase() : this(null)
37 protected ModelPropertyEntryBase(PropertyValue parentValue) : base(parentValue)
42 public abstract PropertyValueSource Source
44 public abstract bool IsMixedValue
46 public abstract Type CommonValueType
48 public abstract TypeConverter Converter
52 // Gets a flag indicating whether this property exposes any sub-properties.
53 // We rely on TypeConverter.GetPropertiesSupported() for this value.
55 public bool HasSubProperties
58 return this.PropertyValue.Value != null && this.Converter != null &&
59 this.Converter.GetPropertiesSupported() && !this.IsMarkupExtension;
63 public abstract PropertyEntryCollection SubProperties
67 // Gets a flag indicating whether the type of the contained property
68 // can be assigned to an IList
70 public bool IsCollection
73 return typeof(IList).IsAssignableFrom(this.PropertyType);
76 public abstract PropertyValueCollection Collection
80 // Gets the depth of this property in the PI sub-property tree
82 public virtual int Depth
90 // Gets a ',' separated path of this property through its
91 // sub-property hierarchy.
93 public string SubPropertyHierarchyPath
96 if (_propertyPath == null)
98 _propertyPath = ModelUtilities.GetSubPropertyHierarchyPath(this);
101 return _propertyPath;
106 // Checks to see if the value of this property comes from a MarkupExtension
108 internal bool IsMarkupExtension
111 DependencyPropertyValueSource source = this.Source as DependencyPropertyValueSource;
112 return source != null && source.IsExpression;
116 internal abstract bool CollectionInstanceExists
120 // Convenience accessor
122 protected ModelPropertyValue ModelPropertyValue
125 return (ModelPropertyValue)this.PropertyValue;
128 public abstract object GetValueCore();
129 public abstract void SetValueCore(object value);
130 public abstract void ClearValue();
132 // Calculate the depth of this property in the sub-property
135 private void UpdateDepth()
137 if (ParentValue != null)
139 _depth = ((ModelPropertyEntryBase)ParentValue.ParentProperty).Depth + 1;
144 // Called when one of the sub-properties exposed by this class changes.
145 // There is a call to the concrete implementation of this class so that it
146 // can do any internal cache clean up as needed, followed by the firing
147 // of the appropriate changed events.
149 public void OnUnderlyingSubModelChanged()
151 OnUnderlyingSubModelChangedCore();
152 this.ModelPropertyValue.OnUnderlyingSubModelChanged();
156 // Called when one of the sub-properties exposed by this class changes
157 // that allows the concrete implementation of this class to clean up
158 // any internal state.
160 protected abstract void OnUnderlyingSubModelChangedCore();
163 // Clears or updates any cached values - call this method
164 // when the underlying ModelProperty changes and cached values
165 // may have become invalid
167 protected virtual void RefreshCache()
170 _propertyPath = null;
173 internal abstract ModelEditingScope BeginEdit(string description);