1 // 2 // Copyright (C) 2010 Novell Inc. http://novell.com 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining 5 // a copy of this software and associated documentation files (the 6 // "Software"), to deal in the Software without restriction, including 7 // without limitation the rights to use, copy, modify, merge, publish, 8 // distribute, sublicense, and/or sell copies of the Software, and to 9 // permit persons to whom the Software is furnished to do so, subject to 10 // the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be 13 // included in all copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 // 23 using System; 24 using System.Collections; 25 using System.Collections.Generic; 26 using System.ComponentModel; 27 using System.Reflection; 28 using System.Windows.Markup; 29 using System.Xaml.Schema; 30 31 namespace System.Windows.Markup 32 { 33 [MarkupExtensionReturnType (typeof (Array))] 34 [ContentProperty ("Items")] 35 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationFramework_3_5)] 36 public class ArrayExtension : MarkupExtension 37 { ArrayExtension()38 public ArrayExtension () 39 { 40 items = new ArrayList (); 41 } 42 ArrayExtension(Array elements)43 public ArrayExtension (Array elements) 44 { 45 if (elements == null) 46 throw new ArgumentNullException ("elements"); 47 Type = elements.GetType ().GetElementType (); 48 items = new ArrayList (elements); 49 } 50 ArrayExtension(Type arrayType)51 public ArrayExtension (Type arrayType) 52 { 53 if (arrayType == null) 54 throw new ArgumentNullException ("arrayType"); 55 Type = arrayType; 56 items = new ArrayList (); 57 } 58 59 [ConstructorArgument ("arrayType")] 60 public Type Type { get; set; } 61 62 IList items; 63 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] 64 public IList Items { 65 get { return items; } 66 } 67 AddChild(Object value)68 public void AddChild (Object value) 69 { 70 // null is allowed. 71 Items.Add (value); 72 } 73 AddText(string text)74 public void AddText (string text) 75 { 76 // null is allowed. 77 Items.Add (text); 78 } 79 ProvideValue(IServiceProvider serviceProvider)80 public override object ProvideValue (IServiceProvider serviceProvider) 81 { 82 if (Type == null) 83 throw new InvalidOperationException ("Type property must be set before calling ProvideValue method"); 84 85 bool invalid = false; 86 foreach (var item in Items) { 87 if (item == null) { 88 if (Type.IsValueType) 89 invalid = true; 90 } 91 else if (!Type.IsAssignableFrom (item.GetType ())) 92 invalid = true; 93 if (invalid) 94 throw new InvalidOperationException (String.Format ("Item in the array must be an instance of '{0}'", Type)); 95 } 96 Array a = Array.CreateInstance (Type, Items.Count); 97 Items.CopyTo (a, 0); 98 return a; 99 } 100 } 101 } 102