1 namespace System.Workflow.ComponentModel.Design 2 { 3 #region Imports 4 5 using System; 6 using System.Drawing.Design; 7 using System.ComponentModel; 8 using System.ComponentModel.Design; 9 using System.Globalization; 10 using System.Collections; 11 using System.Collections.Generic; 12 using System.Reflection; 13 using System.CodeDom; 14 using System.Workflow.ComponentModel.Compiler; 15 using System.Collections.Specialized; 16 using System.Diagnostics; 17 using System.Text; 18 19 #endregion 20 21 #region Class ConditionDeclTypeConverter 22 internal sealed class ConditionTypeConverter : TypeConverter 23 { 24 internal static readonly Type RuleConditionReferenceType = null; 25 internal static readonly Type RuleDefinitionsType = null; 26 internal static readonly Type CodeConditionType = null; 27 internal static DependencyProperty DeclarativeConditionDynamicProp = null; 28 private Hashtable conditionDecls = new Hashtable(); 29 ConditionTypeConverter()30 static ConditionTypeConverter() 31 { 32 RuleConditionReferenceType = Type.GetType("System.Workflow.Activities.Rules.RuleDefinitions, " + AssemblyRef.ActivitiesAssemblyRef); 33 RuleDefinitionsType = Type.GetType("System.Workflow.Activities.Rules.RuleConditionReference, " + AssemblyRef.ActivitiesAssemblyRef); 34 CodeConditionType = Type.GetType("System.Workflow.Activities.CodeCondition, " + AssemblyRef.ActivitiesAssemblyRef); 35 36 DeclarativeConditionDynamicProp = (DependencyProperty)RuleConditionReferenceType.GetField("RuleDefinitionsProperty").GetValue(null); 37 } 38 ConditionTypeConverter()39 public ConditionTypeConverter() 40 { 41 string key = CodeConditionType.FullName; 42 object[] attributes = CodeConditionType.GetCustomAttributes(typeof(DisplayNameAttribute), false); 43 if (attributes != null && attributes.Length > 0 && attributes[0] is DisplayNameAttribute) 44 key = ((DisplayNameAttribute)attributes[0]).DisplayName; 45 this.conditionDecls.Add(key, CodeConditionType); 46 47 key = RuleDefinitionsType.FullName; 48 attributes = RuleDefinitionsType.GetCustomAttributes(typeof(DisplayNameAttribute), false); 49 if (attributes != null && attributes.Length > 0 && attributes[0] is DisplayNameAttribute) 50 key = ((DisplayNameAttribute)attributes[0]).DisplayName; 51 this.conditionDecls.Add(key, RuleDefinitionsType); 52 } 53 CanConvertFrom(ITypeDescriptorContext context, Type sourceType)54 public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 55 { 56 if (sourceType == typeof(string)) 57 return true; 58 return base.CanConvertFrom(context, sourceType); 59 } 60 ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)61 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 62 { 63 if (value is string) 64 { 65 if (((string)value).Length == 0 || ((string)value) == SR.GetString(SR.NullConditionExpression)) 66 return null; 67 else 68 return Activator.CreateInstance(this.conditionDecls[value] as Type); 69 } 70 71 return base.ConvertFrom(context, culture, value); 72 } 73 CanConvertTo(ITypeDescriptorContext context, Type destinationType)74 public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) 75 { 76 if (destinationType == typeof(string)) 77 return true; 78 else 79 return base.CanConvertTo(context, destinationType); 80 } 81 ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)82 public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 83 { 84 if (value == null) 85 return SR.GetString(SR.NullConditionExpression); 86 87 object convertedValue = null; 88 if (destinationType == typeof(string) && value is ActivityCondition) 89 { 90 foreach (DictionaryEntry conditionTypeEntry in this.conditionDecls) 91 { 92 if ((object)value.GetType() == conditionTypeEntry.Value) 93 { 94 convertedValue = conditionTypeEntry.Key; 95 break; 96 } 97 } 98 } 99 100 if (convertedValue == null) 101 convertedValue = base.ConvertTo(context, culture, value, destinationType); 102 103 return convertedValue; 104 } GetStandardValues(ITypeDescriptorContext context)105 public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 106 { 107 ArrayList conditionDeclList = new ArrayList(); 108 109 conditionDeclList.Add(null); 110 foreach (object key in this.conditionDecls.Keys) 111 { 112 Type declType = this.conditionDecls[key] as Type; 113 conditionDeclList.Add(Activator.CreateInstance(declType)); 114 } 115 return new StandardValuesCollection((ActivityCondition[])conditionDeclList.ToArray(typeof(ActivityCondition))); 116 } GetStandardValuesSupported(ITypeDescriptorContext context)117 public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 118 { 119 return true; 120 } GetStandardValuesExclusive(ITypeDescriptorContext context)121 public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 122 { 123 return true; 124 } GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)125 public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) 126 { 127 PropertyDescriptorCollection props = new PropertyDescriptorCollection(new PropertyDescriptor[] { }); 128 129 TypeConverter typeConverter = TypeDescriptor.GetConverter(value.GetType()); 130 if (typeConverter != null && typeConverter.GetType() != GetType() && typeConverter.GetPropertiesSupported()) 131 { 132 return typeConverter.GetProperties(context, value, attributes); 133 } 134 else 135 { 136 IComponent component = PropertyDescriptorUtils.GetComponent(context); 137 if (component != null) 138 props = PropertyDescriptorFilter.FilterProperties(component.Site, value, TypeDescriptor.GetProperties(value, new Attribute[] { BrowsableAttribute.Yes })); 139 } 140 141 return props; 142 } GetPropertiesSupported(ITypeDescriptorContext context)143 public override bool GetPropertiesSupported(ITypeDescriptorContext context) 144 { 145 return true; 146 } 147 } 148 #endregion 149 150 #region ActivityBindTypeConverter 151 [Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")] 152 public class ActivityBindTypeConverter : TypeConverter 153 { ActivityBindTypeConverter()154 public ActivityBindTypeConverter() 155 { 156 } 157 CanConvertFrom(ITypeDescriptorContext context, Type sourceType)158 public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 159 { 160 ITypeDescriptorContext actualContext = null; TypeConverter actualConverter = null; 161 GetActualTypeConverterAndContext(context, out actualConverter, out actualContext); 162 if (actualConverter != null && actualConverter.GetType() != typeof(ActivityBindTypeConverter)) 163 return actualConverter.CanConvertFrom(actualContext, sourceType); 164 else if (sourceType == typeof(string)) 165 return true; 166 167 return base.CanConvertFrom(context, sourceType); 168 } 169 CanConvertTo(ITypeDescriptorContext context, Type destinationType)170 public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) 171 { 172 if (destinationType == typeof(string) && context != null && context.PropertyDescriptor != null) 173 { 174 ActivityBind activityBind = context.PropertyDescriptor.GetValue(context.Instance) as ActivityBind; 175 if (activityBind != null) 176 return true; 177 } 178 179 ITypeDescriptorContext actualContext = null; TypeConverter actualConverter = null; 180 GetActualTypeConverterAndContext(context, out actualConverter, out actualContext); 181 if (actualConverter != null && actualConverter.GetType() != typeof(ActivityBindTypeConverter)) 182 return actualConverter.CanConvertTo(actualContext, destinationType); 183 else if (destinationType == typeof(string)) 184 return true; 185 186 return base.CanConvertTo(context, destinationType); 187 } 188 ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object valueToConvert)189 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object valueToConvert) 190 { 191 string value = valueToConvert as string; 192 if (value == null) 193 return base.ConvertFrom(context, culture, valueToConvert); 194 195 //Trim the value 196 value = value.Trim(); 197 198 //Check if format is "Activity=, Path=" 199 string[] splitParts = Parse(value); 200 object convertedValue = (splitParts.Length == 2) ? new ActivityBind(splitParts[0], splitParts[1]) : null; 201 202 if (convertedValue == null && (context == null || context.PropertyDescriptor == null)) 203 return base.ConvertFrom(context, culture, valueToConvert); 204 205 //For string's only if they begin and end with " we will use the type converter 206 if (convertedValue == null) 207 { 208 ITypeDescriptorContext actualContext = null; TypeConverter actualConverter = null; 209 GetActualTypeConverterAndContext(context, out actualConverter, out actualContext); 210 if (actualConverter != null && actualConverter.GetType() != typeof(ActivityBindTypeConverter) && actualConverter.CanConvertFrom(actualContext, typeof(string))) 211 convertedValue = actualConverter.ConvertFrom(actualContext, culture, value); 212 else 213 convertedValue = valueToConvert; 214 } 215 216 return convertedValue; 217 } 218 ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)219 public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 220 { 221 if (destinationType != typeof(string)) 222 return base.ConvertTo(context, culture, value, destinationType); 223 224 string convertedValue = null; 225 226 ActivityBind activityBind = value as ActivityBind; 227 if (activityBind != null) 228 { 229 Activity activity = PropertyDescriptorUtils.GetComponent(context) as Activity; 230 activity = (activity != null) ? Helpers.ParseActivityForBind(activity, activityBind.Name) : null; 231 convertedValue = String.Format(CultureInfo.InvariantCulture, ("Activity={0}, Path={1}"), (activity != null) ? activity.QualifiedName : activityBind.Name, activityBind.Path); 232 } 233 else 234 { 235 ITypeDescriptorContext actualContext = null; TypeConverter actualConverter = null; 236 GetActualTypeConverterAndContext(context, out actualConverter, out actualContext); 237 if (actualConverter != null && actualConverter.GetType() != typeof(ActivityBindTypeConverter) && actualConverter.CanConvertTo(actualContext, destinationType)) 238 convertedValue = actualConverter.ConvertTo(actualContext, culture, value, destinationType) as string; 239 else 240 convertedValue = base.ConvertTo(context, culture, value, destinationType) as string; 241 } 242 243 return convertedValue; 244 } 245 GetPropertiesSupported(ITypeDescriptorContext context)246 public override bool GetPropertiesSupported(ITypeDescriptorContext context) 247 { 248 bool propertiesSupported = false; 249 if (context != null && context.PropertyDescriptor != null) 250 { 251 ActivityBind activityBind = context.PropertyDescriptor.GetValue(context.Instance) as ActivityBind; 252 if (activityBind != null) 253 { 254 propertiesSupported = true; 255 } 256 else 257 { 258 ITypeDescriptorContext actualContext = null; TypeConverter actualConverter = null; 259 GetActualTypeConverterAndContext(context, out actualConverter, out actualContext); 260 if (actualConverter != null && actualConverter.GetType() != typeof(ActivityBindTypeConverter)) 261 propertiesSupported = actualConverter.GetPropertiesSupported(actualContext); 262 } 263 } 264 265 return propertiesSupported; 266 } 267 GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)268 public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) 269 { 270 ArrayList properties = new ArrayList(); 271 ActivityBind activityBind = value as ActivityBind; 272 if (activityBind != null && context != null) 273 { 274 PropertyDescriptorCollection props = TypeDescriptor.GetProperties(value, new Attribute[] { BrowsableAttribute.Yes }); 275 276 PropertyDescriptor activityDescriptor = props["Name"]; 277 if (activityDescriptor != null) 278 properties.Add(new ActivityBindNamePropertyDescriptor(context, activityDescriptor)); 279 280 PropertyDescriptor pathDescriptor = props["Path"]; 281 if (pathDescriptor != null) 282 properties.Add(new ActivityBindPathPropertyDescriptor(context, pathDescriptor)); 283 } 284 else if (context != null && context.PropertyDescriptor != null) 285 { 286 ITypeDescriptorContext actualContext = null; TypeConverter actualConverter = null; 287 GetActualTypeConverterAndContext(context, out actualConverter, out actualContext); 288 if (actualConverter != null && actualConverter.GetType() != typeof(ActivityBindTypeConverter)) 289 properties.AddRange(actualConverter.GetProperties(actualContext, value, attributes)); 290 } 291 292 return new PropertyDescriptorCollection((PropertyDescriptor[])properties.ToArray(typeof(PropertyDescriptor))); 293 } 294 GetStandardValues(ITypeDescriptorContext context)295 public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 296 { 297 ArrayList valuesList = new ArrayList(); 298 if (context == null || context.PropertyDescriptor == null) 299 return new StandardValuesCollection(new ArrayList()); 300 301 //If the property type supports exclusive values then we need to add them to list 302 ITypeDescriptorContext actualContext = null; TypeConverter actualConverter = null; 303 GetActualTypeConverterAndContext(context, out actualConverter, out actualContext); 304 305 if (actualConverter != null && actualConverter.GetStandardValuesSupported(actualContext) && actualConverter.GetType() != typeof(ActivityBindTypeConverter)) 306 valuesList.AddRange(actualConverter.GetStandardValues(actualContext)); 307 308 return new StandardValuesCollection(valuesList.ToArray()); 309 } 310 GetStandardValuesSupported(ITypeDescriptorContext context)311 public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 312 { 313 //We do not support standard values through the 314 bool standardValuesSupported = false; 315 if (context != null && context.PropertyDescriptor != null) 316 { 317 object existingPropertyValue = (context.Instance != null) ? context.PropertyDescriptor.GetValue(context.Instance) : null; 318 if (!(existingPropertyValue is ActivityBind)) 319 { 320 ITypeDescriptorContext actualContext = null; TypeConverter actualConverter = null; 321 GetActualTypeConverterAndContext(context, out actualConverter, out actualContext); 322 323 if (actualConverter != null && actualConverter.GetType() != typeof(ActivityBindTypeConverter)) 324 standardValuesSupported = actualConverter.GetStandardValuesSupported(actualContext); 325 } 326 } 327 328 return standardValuesSupported; 329 } 330 GetStandardValuesExclusive(ITypeDescriptorContext context)331 public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 332 { 333 bool exclusiveValuesSupported = false; 334 if (context != null && context.PropertyDescriptor != null) 335 { 336 object existingPropertyValue = (context.Instance != null) ? context.PropertyDescriptor.GetValue(context.Instance) : null; 337 if (!(existingPropertyValue is ActivityBind)) 338 { 339 ITypeDescriptorContext actualContext = null; TypeConverter actualConverter = null; 340 GetActualTypeConverterAndContext(context, out actualConverter, out actualContext); 341 342 if (actualConverter != null && actualConverter.GetType() != typeof(ActivityBindTypeConverter)) 343 exclusiveValuesSupported = actualConverter.GetStandardValuesExclusive(actualContext); 344 } 345 } 346 347 return exclusiveValuesSupported; 348 } 349 350 #region Helper Methods GetActualTypeConverterAndContext(ITypeDescriptorContext currentContext, out TypeConverter realTypeConverter, out ITypeDescriptorContext realContext)351 private void GetActualTypeConverterAndContext(ITypeDescriptorContext currentContext, out TypeConverter realTypeConverter, out ITypeDescriptorContext realContext) 352 { 353 //The following case covers the scenario where we have users writting custom property descriptors in which they have returned custom type converters 354 //In such cases we should honor the type converter returned by property descriptor only if it is not a ActivityBindTypeConverter 355 //If it is ActivityBindTypeConveter then we should lookup the converter based on Property type 356 //Please be care ful when you change this code as it will break ParameterInfoBasedPropertyDescriptor 357 realContext = currentContext; 358 realTypeConverter = null; 359 360 if (currentContext != null && currentContext.PropertyDescriptor != null) 361 { 362 realTypeConverter = TypeDescriptor.GetConverter(currentContext.PropertyDescriptor.PropertyType); 363 364 ActivityBindPropertyDescriptor activityBindPropertyDescriptor = currentContext.PropertyDescriptor as ActivityBindPropertyDescriptor; 365 if (activityBindPropertyDescriptor != null && 366 activityBindPropertyDescriptor.RealPropertyDescriptor != null && 367 activityBindPropertyDescriptor.RealPropertyDescriptor.Converter != null && 368 activityBindPropertyDescriptor.RealPropertyDescriptor.Converter.GetType() != typeof(ActivityBindTypeConverter)) 369 { 370 realTypeConverter = activityBindPropertyDescriptor.RealPropertyDescriptor.Converter; 371 realContext = new TypeDescriptorContext(currentContext, activityBindPropertyDescriptor.RealPropertyDescriptor, currentContext.Instance); 372 } 373 } 374 } 375 Parse(string value)376 private string[] Parse(string value) 377 { 378 string[] splitValues = value.Split(new char[] { ',' }, 2); //array could be multi-dimentional 379 if (splitValues.Length == 2) 380 { 381 string activityIDMatch = "Activity="; 382 string pathMatch = "Path="; 383 384 string activityID = splitValues[0].Trim(); 385 string path = splitValues[1].Trim(); 386 if (activityID.StartsWith(activityIDMatch, StringComparison.OrdinalIgnoreCase) && 387 path.StartsWith(pathMatch, StringComparison.OrdinalIgnoreCase)) 388 { 389 activityID = activityID.Substring(activityIDMatch.Length); 390 path = path.Substring(pathMatch.Length); 391 return new String[] { activityID, path }; 392 } 393 } 394 395 return new string[] { }; 396 } 397 #endregion 398 } 399 #endregion 400 401 #region ActivityBindPathTypeConverter 402 internal sealed class ActivityBindPathTypeConverter : PropertyValueProviderTypeConverter 403 { CanConvertFrom(ITypeDescriptorContext context, Type sourceType)404 public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 405 { 406 return new StringConverter().CanConvertFrom(context, sourceType); 407 } 408 CanConvertTo(ITypeDescriptorContext context, Type destinationType)409 public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) 410 { 411 return new StringConverter().CanConvertTo(context, destinationType); 412 } 413 ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)414 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 415 { 416 return new StringConverter().ConvertFrom(context, culture, value); 417 } 418 ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)419 public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 420 { 421 return new StringConverter().ConvertTo(context, culture, value, destinationType); 422 } 423 } 424 #endregion 425 } 426