1 //------------------------------------------------------------------------------
2 // <copyright file="ModelProperty.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 namespace System.Activities.Presentation.Model {
9 using System.Activities.Presentation.Internal.Properties;
11 using System.ComponentModel;
12 using System.Diagnostics.CodeAnalysis;
13 using System.Globalization;
17 /// An ModelProperty represents a property on an item. ModelProperties are
18 /// associated with an instance of an item, which allows them to have simple
19 /// Value get/set properties instead of the more cumbersome GetValue/SetValue
20 /// mechanism of PropertyDescriptor.
22 /// A ModelProperty
\92s value may come from a locally set value, or it may be
23 /// inherited from somewhere higher up in the property mechanism. Because
24 /// all items in the tree contain Source properties, you can
25 /// easily find out the real source of a property value simply using the
28 /// Console.WriteLine(property.Value.Source);
30 /// Value will return null if the property is not set anywhere in the hierarchy.
32 /// Type converters and editors defined on the underlying data model are
33 /// wrapped so that they accept ModelItems as parameters.
35 public abstract class ModelProperty {
38 /// Creates a new ModelProperty.
40 protected ModelProperty() { }
43 /// Returns the attributes declared on this property.
45 public abstract AttributeCollection Attributes { get; }
48 /// Returns Value cast as a ModelItemCollection. This property allows you to
49 /// access collection properties easily without cluttering your code with casts:
51 /// Property.Collection.Add(myItem);
53 /// If the property value is not a collection, this property will return null.
55 [Fx.Tag.KnownXamlExternalAttribute]
56 public abstract ModelItemCollection Collection { get; }
59 /// Returns the currently computed value for this property. Setting a value
60 /// on this property is the same as calling SetValue, but can be used in
61 /// data binding expressions.
63 public abstract object ComputedValue { get; set; }
66 /// Returns the type converter to use with this property. Underlying type
67 /// converters are all wrapped so they accept Item objects. When performing
68 /// a conversion to a particular value, the type converter
\92s return type is
69 /// not wrapped. Type converters which return standard values also return
70 /// values as Item objects.
72 public abstract TypeConverter Converter { get; }
75 /// Returns the type which defines this property if IsAttached returns true.
76 /// Otherwhise, returns null.
78 public abstract Type AttachedOwnerType { get; }
81 /// Returns the default value for this property. If the property does not
82 /// define a default value this will return null.
84 public abstract object DefaultValue { get; }
87 /// Returns Value cast as a ItemDictionary. This property allows you to
88 /// access dictionary properties easily without cluttering your code with casts:
90 /// Property.Dictionary[key] = value;
92 /// If the property value is not a dictionary, this property will return null.
94 [Fx.Tag.KnownXamlExternalAttribute]
95 public abstract ModelItemDictionary Dictionary { get; }
98 /// Returns true if the property can be shown in a property window.
100 public abstract bool IsBrowsable { get; }
103 /// Returns true if the value contained in the property is a ItemCollection.
105 public abstract bool IsCollection { get; }
108 /// Returns true if the value contained in the property is a ItemDictionary.
110 public abstract bool IsDictionary { get; }
113 /// Returns true if the property is read only.
115 public abstract bool IsReadOnly { get; }
118 /// Returns true if the property
\92s value is set locally.
120 public abstract bool IsSet { get; }
123 /// Returns true if the property represents an attached property from a different type.
125 public abstract bool IsAttached { get; }
128 /// Returns the value set into this property. A property may return a
129 /// value that is inherited further up the element hierarchy, in which
130 /// case this property will return a value whose source != this.
131 /// If no value has ever been set for the property Value will return null.
133 public abstract ModelItem Value { get; }
136 /// Returns the name of this property.
138 public abstract string Name { get; }
141 /// Returns the parent of this property. All properties have
142 /// parents, so this never returns null.
144 public abstract ModelItem Parent { get; }
147 /// The data type of the property.
149 public abstract Type PropertyType { get; }
152 /// Clears the local value for the property.
154 public abstract void ClearValue();
157 /// Sets a local value on a property. If this value is already
158 /// a ModelItem, it will be used directly. If it isn
\92t, a ModelItem
159 /// will be created. Setting null into a property is valid, but
160 /// this is not the same as calling ClearValue().
162 /// <param name="value">
163 /// The new value to set.
166 /// The input value, if the value is already a ModelItem, or a newly
167 /// created ModelItem wrapping the value.
169 public abstract ModelItem SetValue(object value);
171 internal virtual string Reference
179 internal virtual void ClearReference()
183 internal virtual void SetReference(string sourceProperty)
188 /// Equality operator.
190 // FXCop: args are validated; fxcop does not seem to understand ReferenceEquals.
192 public static bool operator ==(ModelProperty first, ModelProperty second) {
193 if (object.ReferenceEquals(first, second)) return true;
194 if (object.ReferenceEquals(first, null) || object.ReferenceEquals(second, null)) return false;
195 return (first.Parent == second.Parent && first.Name.Equals(second.Name));
199 /// Inequality operator.
201 // FXCop: args are validated; fxcop does not seem to understand ReferenceEquals.
203 public static bool operator !=(ModelProperty first, ModelProperty second) {
204 if (object.ReferenceEquals(first, second)) return false;
205 if (object.ReferenceEquals(first, null) || object.ReferenceEquals(second, null)) return true;
206 return (first.Parent != second.Parent || !first.Name.Equals(second.Name));
210 /// Equality for properties. Properties are equal if
211 /// they have the same name and parent.
213 /// <param name="obj"></param>
214 /// <returns></returns>
215 public override bool Equals(object obj) {
216 if (object.ReferenceEquals(obj, this)) return true;
217 ModelProperty prop = obj as ModelProperty;
218 if (object.ReferenceEquals(prop, null)) return false;
219 if (prop.Parent != Parent) return false;
220 return prop.Name.Equals(Name);
224 /// Standard hashcode implementation.
226 /// <returns></returns>
227 public override int GetHashCode() {
228 return Parent.GetHashCode() ^ Name.GetHashCode();