1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Globalization; 6 7 namespace System.ComponentModel 8 { 9 /// <summary> 10 /// <para>Provides a type converter to convert <see cref='System.Array'/> 11 /// objects to and from various other representations.</para> 12 /// </summary> 13 public class ArrayConverter : CollectionConverter 14 { 15 /// <summary> 16 /// <para>Converts the given value object to the specified destination type.</para> 17 /// </summary> ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)18 public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 19 { 20 if (destinationType == null) 21 { 22 throw new ArgumentNullException(nameof(destinationType)); 23 } 24 25 if (destinationType == typeof(string) && value is Array) 26 { 27 return SR.Format(SR.Array, value.GetType().Name); 28 } 29 30 return base.ConvertTo(context, culture, value, destinationType); 31 } 32 33 /// <summary> 34 /// <para>Gets a collection of properties for the type of array specified by the value parameter.</para> 35 /// </summary> GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)36 public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) 37 { 38 if (value == null) 39 { 40 return null; 41 } 42 43 PropertyDescriptor[] props = null; 44 45 if (value.GetType().IsArray) 46 { 47 Array valueArray = (Array)value; 48 int length = valueArray.GetLength(0); 49 props = new PropertyDescriptor[length]; 50 51 Type arrayType = value.GetType(); 52 Type elementType = arrayType.GetElementType(); 53 54 for (int i = 0; i < length; i++) 55 { 56 props[i] = new ArrayPropertyDescriptor(arrayType, elementType, i); 57 } 58 } 59 60 return new PropertyDescriptorCollection(props); 61 } 62 63 /// <summary> 64 /// <para>Gets a value indicating whether this object supports properties.</para> 65 /// </summary> GetPropertiesSupported(ITypeDescriptorContext context)66 public override bool GetPropertiesSupported(ITypeDescriptorContext context) 67 { 68 return true; 69 } 70 71 private class ArrayPropertyDescriptor : SimplePropertyDescriptor 72 { 73 private readonly int _index; 74 ArrayPropertyDescriptor(Type arrayType, Type elementType, int index)75 public ArrayPropertyDescriptor(Type arrayType, Type elementType, int index) 76 : base(arrayType, "[" + index + "]", elementType, null) 77 { 78 _index = index; 79 } 80 GetValue(object instance)81 public override object GetValue(object instance) 82 { 83 var array = instance as Array; 84 if (array != null && array.GetLength(0) > _index) 85 { 86 return array.GetValue(_index); 87 } 88 89 return null; 90 } 91 SetValue(object instance, object value)92 public override void SetValue(object instance, object value) 93 { 94 if (instance is Array) 95 { 96 Array array = (Array)instance; 97 if (array.GetLength(0) > _index) 98 { 99 array.SetValue(value, _index); 100 } 101 102 OnValueChanged(instance, EventArgs.Empty); 103 } 104 } 105 } 106 } 107 } 108