1 // Copyright (c) Microsoft Corporation. All rights reserved.
3 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
4 // WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
5 // WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
6 // THE ENTIRE RISK OF USE OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE
7 // AND INFORMATION REMAINS WITH THE USER.
10 /*********************************************************************
11 * NOTE: A copy of this file exists at: WF\Activities\Common
12 * The two files must be kept in sync. Any change made here must also
13 * be made to WF\Activities\Common\Walker.cs
14 *********************************************************************/
15 namespace System
.Workflow
.ComponentModel
20 using System
.Collections
;
21 using System
.Collections
.Generic
;
22 using System
.Reflection
;
23 using System
.ComponentModel
;
24 using System
.Diagnostics
.CodeAnalysis
;
28 // Returns true to continue the walk, false to stop.
29 internal delegate void WalkerEventHandler(Walker walker
, WalkerEventArgs eventArgs
);
31 internal enum WalkerAction
37 #region Class WalkerEventArgs
39 internal sealed class WalkerEventArgs
: EventArgs
41 private Activity currentActivity
= null;
42 private object currentPropertyOwner
= null;
43 private PropertyInfo currentProperty
= null;
44 private object currentValue
= null;
45 private WalkerAction action
= WalkerAction
.Continue
;
47 internal WalkerEventArgs(Activity currentActivity
)
49 this.currentActivity
= currentActivity
;
50 this.currentPropertyOwner
= null;
51 this.currentProperty
= null;
52 this.currentValue
= null;
55 internal WalkerEventArgs(Activity currentActivity
, object currentValue
, PropertyInfo currentProperty
, object currentPropertyOwner
)
56 : this(currentActivity
)
58 this.currentPropertyOwner
= currentPropertyOwner
;
59 this.currentProperty
= currentProperty
;
60 this.currentValue
= currentValue
;
63 public WalkerAction Action
75 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
76 public PropertyInfo CurrentProperty
80 return this.currentProperty
;
84 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
85 public object CurrentPropertyOwner
89 return this.currentPropertyOwner
;
93 [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
94 public object CurrentValue
98 return this.currentValue
;
102 public Activity CurrentActivity
106 return this.currentActivity
;
113 internal sealed class Walker
117 internal event WalkerEventHandler FoundActivity
;
118 internal event WalkerEventHandler FoundProperty
;
119 private bool useEnabledActivities
= false;
130 public Walker(bool useEnabledActivities
)
132 this.useEnabledActivities
= useEnabledActivities
;
135 public void Walk(Activity seedActivity
)
137 Walk(seedActivity
, true);
140 public void Walk(Activity seedActivity
, bool walkChildren
)
142 Queue queue
= new Queue();
144 queue
.Enqueue(seedActivity
);
145 while (queue
.Count
> 0)
147 Activity activity
= queue
.Dequeue() as Activity
;
149 if (FoundActivity
!= null)
151 WalkerEventArgs args
= new WalkerEventArgs(activity
);
152 FoundActivity(this, args
);
153 if (args
.Action
== WalkerAction
.Abort
)
155 if (args
.Action
== WalkerAction
.Skip
)
159 if (FoundProperty
!= null)
161 if (!WalkProperties(activity
))
165 if (walkChildren
&& activity
is CompositeActivity
)
167 if (useEnabledActivities
)
169 foreach (Activity activity2
in Design
.Helpers
.GetAllEnabledActivities((CompositeActivity
)activity
))
170 queue
.Enqueue(activity2
);
174 foreach (Activity activity2
in ((CompositeActivity
)activity
).Activities
)
175 queue
.Enqueue(activity2
);
181 private bool WalkProperties(Activity seedActivity
)
183 return WalkProperties(seedActivity
as Activity
, seedActivity
);
186 public bool WalkProperties(Activity activity
, object obj
)
188 Activity currentActivity
= obj
as Activity
;
190 PropertyInfo
[] props
= obj
.GetType().GetProperties(BindingFlags
.Public
| BindingFlags
.Instance
);
191 foreach (PropertyInfo prop
in props
)
193 // !!Work around: no indexer property walking
194 if (prop
.GetIndexParameters() != null && prop
.GetIndexParameters().Length
> 0)
197 DesignerSerializationVisibility visibility
= GetSerializationVisibility(prop
);
198 if (visibility
== DesignerSerializationVisibility
.Hidden
)
201 //Try to see if we have dynamic property associated with the object on the same object
202 //if so then we should compare if the dynamic property values match with the property type
204 object propValue
= null;
205 DependencyProperty dependencyProperty
= DependencyProperty
.FromName(prop
.Name
, obj
.GetType());
206 if (dependencyProperty
!= null && currentActivity
!= null)
208 if (currentActivity
.IsBindingSet(dependencyProperty
))
209 propValue
= currentActivity
.GetBinding(dependencyProperty
);
211 propValue
= currentActivity
.GetValue(dependencyProperty
);
217 propValue
= prop
.CanRead
? prop
.GetValue(obj
, null) : null;
221 // Eat exceptions that occur while invoking the getter.
225 if (FoundProperty
!= null)
227 WalkerEventArgs args
= new WalkerEventArgs(activity
, propValue
, prop
, obj
);
228 FoundProperty(this, args
);
229 if (args
.Action
== WalkerAction
.Skip
)
231 else if (args
.Action
== WalkerAction
.Abort
)
235 if (propValue
is IList
)
237 //We do not need to reflect on the properties of the list
238 foreach (object childObj
in (IList
)propValue
)
240 if (FoundProperty
!= null)
242 WalkerEventArgs args
= new WalkerEventArgs(activity
, childObj
, null, propValue
);
243 FoundProperty(this, args
);
244 if (args
.Action
== WalkerAction
.Skip
)
246 else if (args
.Action
== WalkerAction
.Abort
)
249 if (childObj
!= null && IsBrowsableType(childObj
.GetType()))
251 if (!WalkProperties(activity
, childObj
))
256 else if (propValue
!= null && IsBrowsableType(propValue
.GetType()))
258 if (!WalkProperties(activity
, propValue
))
265 private static DesignerSerializationVisibility
GetSerializationVisibility(PropertyInfo prop
)
267 // work around!!! for Activities collection
268 if (prop
.DeclaringType
== typeof(CompositeActivity
) && string.Equals(prop
.Name
, "Activities", StringComparison
.Ordinal
))
269 return DesignerSerializationVisibility
.Hidden
;
271 DesignerSerializationVisibility visibility
= DesignerSerializationVisibility
.Visible
;
272 DesignerSerializationVisibilityAttribute
[] visibilityAttrs
= (DesignerSerializationVisibilityAttribute
[])prop
.GetCustomAttributes(typeof(DesignerSerializationVisibilityAttribute
), true);
273 if (visibilityAttrs
.Length
> 0)
274 visibility
= visibilityAttrs
[0].Visibility
;
279 private static bool IsBrowsableType(Type type
)
281 bool browsable
= false;
282 BrowsableAttribute
[] browsableAttrs
= (BrowsableAttribute
[])type
.GetCustomAttributes(typeof(BrowsableAttribute
), true);
283 if (browsableAttrs
.Length
> 0)
284 browsable
= browsableAttrs
[0].Browsable
;