[reflection] Coop handles icalls in System.Reflection and System.RuntimeTypeHandle...
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / Model / ModelPropertyCollectionImpl.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.Activities.Presentation.View;
9     using System.ComponentModel;
10     using System.IO;
11     using System.Linq;
12
13
14     // This provides a container for model properties of a modelItem.
15     // This uses the TypeDescriptor.GetProperties() instead of using reflection
16     // to get the properties of a model item. So any model instance implementing ICustomTypeProvider 
17     // is automatically taken care of.
18
19     class ModelPropertyCollectionImpl : ModelPropertyCollection
20     {
21         ModelItem parent;
22         bool createFakeModelProperties;
23
24         public ModelPropertyCollectionImpl(ModelItem parent)
25         {
26             this.parent = parent;
27             createFakeModelProperties = this.parent is FakeModelItemImpl;
28         }
29
30         public override IEnumerator<ModelProperty> GetEnumerator()
31         {
32             foreach (PropertyDescriptor propertyDescriptor in GetPropertyDescriptors())
33             {
34                 yield return CreateProperty(parent, propertyDescriptor);
35             }
36         }
37
38         protected override ModelProperty Find(System.Windows.DependencyProperty value, bool throwOnError)
39         {
40             // We dont support dependency properties.
41             if (throwOnError)
42             {
43                 throw FxTrace.Exception.AsError(new NotSupportedException());
44             }
45             else
46             {
47                 return null;
48             }
49         }
50
51         protected override ModelProperty Find(string name, bool throwOnError)
52         {
53             PropertyDescriptor propertyDescriptor = GetPropertyDescriptors()[name];
54             if (propertyDescriptor != null)
55             {
56                 return CreateProperty(parent, propertyDescriptor);
57             }
58             return null;
59         }
60
61         ModelProperty CreateProperty(ModelItem parent, PropertyDescriptor propertyDescriptor)
62         {
63             bool isAttached = propertyDescriptor is AttachedPropertyDescriptor;
64             return this.createFakeModelProperties ?
65                 (ModelProperty)(new FakeModelPropertyImpl((FakeModelItemImpl)parent, propertyDescriptor)) :
66                 (ModelProperty)(new ModelPropertyImpl(parent, propertyDescriptor, isAttached));
67         }
68
69         PropertyDescriptorCollection GetPropertyDescriptors()
70         {
71             PropertyDescriptorCollection propertyDescriptors = PropertyDescriptorCollection.Empty;
72
73             try
74             {
75                 object instance = parent.GetCurrentValue();
76                 if (instance != null)
77                 {
78                     if (!(instance is ICustomTypeDescriptor))
79                     {
80                         Type instanceType = instance.GetType();
81                         if (instanceType.IsValueType)
82                         {
83                             propertyDescriptors = TypeDescriptor.GetProvider(instanceType).GetTypeDescriptor(instanceType).GetProperties();
84                         }
85                         else
86                         {
87                             propertyDescriptors = TypeDescriptor.GetProvider(instance).GetTypeDescriptor(instance).GetProperties();
88                         }
89                     }
90                     else
91                     {
92                         propertyDescriptors = TypeDescriptor.GetProperties(instance);
93                     }
94
95                 }
96
97                 // Add browsable attached properties 
98                 AttachedPropertiesService AttachedPropertiesService = this.parent.GetEditingContext().Services.GetService<AttachedPropertiesService>();
99                 if (AttachedPropertiesService != null)
100                 {
101
102                     var browsableAttachedProperties = from attachedProperty in AttachedPropertiesService.GetAttachedProperties(this.parent.ItemType)
103                                                       where (attachedProperty.IsBrowsable || attachedProperty.IsVisibleToModelItem)
104                                                       select new AttachedPropertyDescriptor(attachedProperty, this.parent);
105
106                     List<PropertyDescriptor> mergedProperties = new List<PropertyDescriptor>();
107                     foreach (PropertyDescriptor propertyDescriptor in propertyDescriptors)
108                     {
109                         mergedProperties.Add(propertyDescriptor);
110                     }
111                     propertyDescriptors = new PropertyDescriptorCollection(mergedProperties.Concat(browsableAttachedProperties).ToArray(), true);
112
113                 }
114             }
115             catch (FileNotFoundException e)
116             {
117                 EditingContext context = parent.GetEditingContext();
118                 if (context.Items.GetValue<ErrorItem>() == null)
119                 {
120                     context.Items.SetValue(new ErrorItem { Message = e.Message, Details = e.ToString() });
121                 }
122             }
123
124             return propertyDescriptors;
125         }
126     }
127 }