1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //-----------------------------------------------------------------------------
5 namespace System.Activities.Presentation.Model
9 using System.Collections;
10 using System.Collections.Generic;
11 using System.ComponentModel;
12 using System.Globalization;
13 using System.Diagnostics.CodeAnalysis;
15 // This is a type converter that wraps another type converter. In the
16 // editing model, we expose all properties as ModelItem objects, so we need
17 // to unwrap them before handing them to a type converter. This type
18 // converter provides that unwrapping seamlessly.
20 [SuppressMessage("XAML", "XAML1004", Justification = "This is internal, and is always available through TypeConverter.GetConverter, not used in xaml")]
21 class ModelTypeConverter : TypeConverter
24 ModelTreeManager modelTreeManager;
25 TypeConverter converter;
27 internal ModelTypeConverter(ModelTreeManager modelTreeManager, TypeConverter converter)
29 this.modelTreeManager = modelTreeManager;
30 this.converter = converter;
33 // Wraps the given type descriptor context with the set of this.modelTreeManagers
34 // available in the editing context.
35 ITypeDescriptorContext WrapContext(ITypeDescriptorContext context)
37 return new ModelTypeDescriptorContextWrapper(context, this.modelTreeManager);
40 // Returns true if the converter can convert from the given source type.
41 public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
43 if (sourceType == null)
45 throw FxTrace.Exception.AsError(new ArgumentNullException("sourceType"));
47 return this.converter.CanConvertFrom(WrapContext(context), sourceType);
50 // Returns true if the converter can convert to the given target type.
51 public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
53 if (destinationType == null)
55 throw FxTrace.Exception.AsError(new ArgumentNullException("destinationType"));
57 return this.converter.CanConvertTo(WrapContext(context), destinationType);
60 // Performs the actual conversion from one type to antother. If the value provided
61 // is a ModelItem, it will be unwrapped first. The return value is a ModelItem.
62 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
64 ModelItem item = value as ModelItem;
67 value = item.GetCurrentValue();
69 object convertedValue = this.converter.ConvertFrom(WrapContext(context), culture, value);
71 if (convertedValue != null)
73 convertedValue = this.modelTreeManager.CreateModelItem(null, convertedValue);
76 return convertedValue;
79 // Performs the actual conversion to another type. If the value provided is an item, it will
80 // be uwrapped first. The return value is the raw data type.
81 public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
83 ModelItem item = value as ModelItem;
86 value = item.GetCurrentValue();
90 return this.converter.ConvertTo(WrapContext(context), culture, value, destinationType);
95 // Creates an instance of an object using a dictionary of property values. The
96 // return value is a wrapped model item.
97 public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
99 object value = this.converter.CreateInstance(WrapContext(context), propertyValues);
102 value = this.modelTreeManager.CreateModelItem(null, value);
107 // Returns true if the CreateInstance method can be used to create new instances of
109 public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
111 return this.converter.GetCreateInstanceSupported(WrapContext(context));
114 // Returns child properties for a type converter. This will wrap all properties returned.
115 public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
120 throw FxTrace.Exception.AsError( new ArgumentNullException("value"));
123 ModelItem item = value as ModelItem;
126 value = item.GetCurrentValue();
129 PropertyDescriptorCollection props = this.converter.GetProperties(WrapContext(context), value, attributes);
130 if (props != null && props.Count > 0)
135 // We will need the item for this object.
136 item = this.modelTreeManager.CreateModelItem(null, value);
139 // Search our item for each property and wrap it. If
140 // a property is not offered by the model, ommit it.
142 List<PropertyDescriptor> newProps = new List<PropertyDescriptor>(props.Count);
143 foreach (PropertyDescriptor p in props)
145 ModelProperty modelProp = item.Properties.Find(p.Name);
146 if (modelProp != null)
148 newProps.Add(new ModelPropertyDescriptor(modelProp));
152 props = new PropertyDescriptorCollection(newProps.ToArray(), true);
158 // Returns true if GetProperties will return child properties for the
160 public override bool GetPropertiesSupported(ITypeDescriptorContext context)
162 return this.converter.GetPropertiesSupported(WrapContext(context));
165 // Returns a set of standard values this type converter offers.
166 public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
168 StandardValuesCollection values = this.converter.GetStandardValues(WrapContext(context));
170 // Some type converters return null here, which isn't supposed to
171 // be allowed. Fix them
173 object[] wrappedValues;
177 wrappedValues = new object[0];
181 wrappedValues = new object[values.Count];
183 foreach (object value in values)
188 wrappedValue = this.modelTreeManager.CreateModelItem(null, value);
192 wrappedValue = value;
195 wrappedValues[idx++] = wrappedValue;
199 return new StandardValuesCollection(wrappedValues);
202 // Returns true if the set of standard values cannot be customized.
203 public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
205 return this.converter.GetStandardValuesExclusive(WrapContext(context));
208 // Returns true if this type converter offers a set of standard values.
209 public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
211 return this.converter.GetStandardValuesSupported(WrapContext(context));
214 // Returns true if the given value is a valid value for this type converter.
215 public override bool IsValid(ITypeDescriptorContext context, object value)
217 ModelItem item = value as ModelItem;
220 value = item.GetCurrentValue();
222 return this.converter.IsValid(WrapContext(context), value);