Merge branch 'alexischr/nursery-canaries-managed-alloc'
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / Model / ModelPropertyImpl.cs
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4
5 namespace System.Activities.Presentation.Model
6 {
7     using System.Collections.Generic;
8     using System.ComponentModel;
9     using System.Windows.Documents;
10
11     // This class provides the implementation for a model property.
12     // this intercepts sets /gets to the property and works with modeltreemanager
13     // to keep the xaml in [....].
14
15     class ModelPropertyImpl : ModelProperty
16     {
17         object defaultValue;
18         ModelItem parent;
19         PropertyDescriptor propertyDescriptor;
20         bool isAttached = false;
21
22         public ModelPropertyImpl(ModelItem parent, PropertyDescriptor propertyDescriptor, bool isAttached)
23         {
24             this.parent = parent;
25             this.propertyDescriptor = propertyDescriptor;
26
27             // using this a marker to indicate this hasnt been computed yet.
28             this.defaultValue = this;
29             this.isAttached = isAttached;
30         }
31
32         public override Type AttachedOwnerType
33         {
34             get
35             {
36                 return this.parent.GetType();
37             }
38         }
39
40         public override AttributeCollection Attributes
41         {
42             get
43             {
44                 return this.propertyDescriptor.Attributes;
45             }
46         }
47
48         public override ModelItemCollection Collection
49         {
50             get
51             {
52                 return this.Value as ModelItemCollection;
53             }
54         }
55
56         public override object ComputedValue
57         {
58             get
59             {
60                 object computedValue = null;
61                 if (this.Value != null)
62                 {
63                     computedValue = Value.GetCurrentValue();
64                 }
65                 return computedValue;
66             }
67             set
68             {
69                 SetValue(value);
70             }
71         }
72
73         public override System.ComponentModel.TypeConverter Converter
74         {
75             get
76             {
77                 return new ModelTypeConverter(((IModelTreeItem)this.Parent).ModelTreeManager, propertyDescriptor.Converter);
78             }
79         }
80
81         public override object DefaultValue
82         {
83             get
84             {
85                 if (Object.ReferenceEquals(this.defaultValue, this))
86                 {
87                     DefaultValueAttribute defaultValueAttribute = this.propertyDescriptor.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute;
88                     this.defaultValue = (defaultValueAttribute == null) ? null : defaultValueAttribute.Value;
89                 }
90                 return this.defaultValue;
91             }
92         }
93
94         public override ModelItemDictionary Dictionary
95         {
96             get
97             {
98                 return Value as ModelItemDictionary;
99             }
100         }
101
102         public override bool IsAttached
103         {
104             get
105             {
106                 return this.isAttached;
107             }
108         }
109
110         public override bool IsBrowsable
111         {
112             get
113             {
114                 return propertyDescriptor.IsBrowsable;
115             }
116         }
117
118         public override bool IsCollection
119         {
120             get { return this.Value is ModelItemCollection; }
121         }
122
123         public override bool IsDictionary
124         {
125             get { return this.Value is ModelItemDictionary; }
126         }
127
128         public override bool IsReadOnly
129         {
130             get
131             {
132                 return propertyDescriptor.IsReadOnly;
133             }
134         }
135
136         public override bool IsSet
137         {
138             get
139             {
140                 return this.Value != null;
141             }
142         }
143
144         public override string Name
145         {
146             get
147             {
148                 return propertyDescriptor.Name;
149             }
150         }
151
152         public override ModelItem Parent
153         {
154             get
155             {
156                 return parent;
157             }
158         }
159
160         public override Type PropertyType
161         {
162             get
163             {
164                 return propertyDescriptor.PropertyType;
165             }
166         }
167
168         public override ModelItem Value
169         {
170             get
171             {
172                 return ((IModelTreeItem)parent).ModelTreeManager.GetValue(this);
173             }
174         }
175
176         internal PropertyDescriptor PropertyDescriptor
177         {
178             get
179             {
180                 return propertyDescriptor;
181             }
182         }
183
184         public override void ClearValue()
185         {
186             if (!this.IsReadOnly)
187             {
188                 ((IModelTreeItem)parent).ModelTreeManager.ClearValue(this);
189             }
190         }
191
192         public override ModelItem SetValue(object value)
193         {
194             return ((IModelTreeItem)parent).ModelTreeManager.SetValue(this, value);
195         }
196
197         internal override string Reference
198         {
199             get
200             {
201                 return PropertyReferenceUtilities.GetPropertyReference(parent.GetCurrentValue(), this.Name);
202             }
203         }
204
205         internal override void ClearReference()
206         {
207             this.SetReference(null);
208         }
209
210         internal override void SetReference(string sourceProperty)
211         {
212             PropertyReferenceChange change = new PropertyReferenceChange()
213             {
214                 Owner = this.Parent,
215                 TargetProperty = this.Name,
216                 OldSourceProperty = this.Reference,
217                 NewSourceProperty = sourceProperty
218             };
219
220             ((IModelTreeItem)parent).ModelTreeManager.AddToCurrentEditingScope(change);
221         }
222
223         internal object SetValueCore(ModelItem newValueModelItem)
224         {
225             object newValueInstance = (newValueModelItem == null) ? null : newValueModelItem.GetCurrentValue();
226             ModelItem oldValueModelItem = this.Value;
227             IModelTreeItem parent = (IModelTreeItem)this.Parent;
228
229             // update object instance
230             this.PropertyDescriptor.SetValue(this.Parent.GetCurrentValue(), newValueInstance);
231
232             if (oldValueModelItem != null && !this.isAttached)
233             {
234                 parent.ModelPropertyStore.Remove(this.Name);
235                 parent.ModelTreeManager.OnPropertyEdgeRemoved(this.Name, this.Parent, oldValueModelItem);
236             }
237
238             if (newValueModelItem != null && !this.isAttached)
239             {
240                 parent.ModelPropertyStore.Add(this.Name, newValueModelItem);
241                 parent.ModelTreeManager.OnPropertyEdgeAdded(this.Name, this.Parent, newValueModelItem);
242             }
243
244             // notify observers
245             ((IModelTreeItem)this.Parent).OnPropertyChanged(this.Name);
246             return newValueInstance;
247         }
248     }
249 }