2 // Copyright (C) 2010 Novell Inc. http://novell.com
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:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
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.
24 using System.Collections;
25 using System.Collections.Generic;
26 using System.Collections.ObjectModel;
27 using System.ComponentModel;
28 using System.Diagnostics;
29 using System.Globalization;
32 using System.Reflection;
33 using System.Windows.Markup;
35 using System.Xaml.Schema;
37 using System.Xml.Schema;
38 using System.Xml.Serialization;
40 [assembly: XmlnsDefinition ("http://www.domain.com/path", "XamlTest")] // bug #680385
41 [assembly: XmlnsDefinition ("http://www.domain.com/path", "SecondTest")] // bug #681045, same xmlns key for different clrns.
43 [assembly: XmlnsDefinition ("http://schemas.example.com/test", "XamarinBug3003")] // bug #3003
44 [assembly: XmlnsPrefix ("http://schemas.example.com/test", "test")] // bug #3003
46 namespace MonoTests.System.Xaml
48 public class ArgumentAttributed
50 public ArgumentAttributed (string s1, string s2)
56 [ConstructorArgument ("s1")]
57 public string Arg1 { get; set; }
59 [ConstructorArgument ("s2")]
60 public string Arg2 { get; set; }
63 public class ComplexPositionalParameterWrapper
65 public ComplexPositionalParameterWrapper ()
69 public ComplexPositionalParameterClass Param { get; set; }
72 [TypeConverter (typeof (ComplexPositionalParameterClassConverter))]
73 public class ComplexPositionalParameterClass : MarkupExtension
75 public ComplexPositionalParameterClass (ComplexPositionalParameterValue value)
80 [ConstructorArgument ("value")]
81 public ComplexPositionalParameterValue Value { get; private set; }
83 public override object ProvideValue (IServiceProvider sp)
89 public class ComplexPositionalParameterClassConverter : TypeConverter
91 public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
93 return sourceType == typeof (string);
96 public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object valueToConvert)
98 return new ComplexPositionalParameterClass (new ComplexPositionalParameterValue () {Foo = (string) valueToConvert});
101 public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType)
103 // conversion to string is not supported.
104 return destinationType == typeof (ComplexPositionalParameterClass);
108 public class ComplexPositionalParameterValue
110 public string Foo { get; set; }
113 //[MarkupExtensionReturnType (typeof (Array))]
114 //[ContentProperty ("Items")] ... so, these attributes do not affect XamlObjectReader.
115 public class MyArrayExtension : MarkupExtension
117 public MyArrayExtension ()
119 items = new ArrayList ();
122 public MyArrayExtension (Array array)
124 items = new ArrayList (array);
125 this.Type = array.GetType ().GetElementType ();
128 public MyArrayExtension (Type type)
136 get { return items; }
137 private set { items = value; }
140 [ConstructorArgument ("type")]
141 public Type Type { get; set; }
143 public override object ProvideValue (IServiceProvider serviceProvider)
146 throw new InvalidOperationException ("Type property must be set before calling ProvideValue method");
148 Array a = Array.CreateInstance (Type, Items.Count);
154 // The trailing "A" gives significant difference in XML output!
155 public class MyArrayExtensionA : MarkupExtension
157 public MyArrayExtensionA ()
159 items = new ArrayList ();
162 public MyArrayExtensionA (Array array)
164 items = new ArrayList (array);
165 this.Type = array.GetType ().GetElementType ();
168 public MyArrayExtensionA (Type type)
176 get { return items; }
177 private set { items = value; }
180 [ConstructorArgument ("type")]
181 public Type Type { get; set; }
183 public override object ProvideValue (IServiceProvider serviceProvider)
186 throw new InvalidOperationException ("Type property must be set before calling ProvideValue method");
188 Array a = Array.CreateInstance (Type, Items.Count);
198 public class TestClass3
200 public TestClass3 Nested { get; set; }
203 public class TestClass4
205 public string Foo { get; set; }
206 public string Bar { get; set; }
209 public class TestClass5
211 public static string Foo { get; set; }
212 public string Bar { get; set; }
213 public string Baz { internal get; set; }
214 public string ReadOnly {
219 public class MyExtension : MarkupExtension
221 public MyExtension ()
225 public MyExtension (Type arg1, string arg2, string arg3)
232 [ConstructorArgument ("arg1")]
233 public Type Foo { get; set; }
235 [ConstructorArgument ("arg2")]
236 public string Bar { get; set; }
238 [ConstructorArgument ("arg3")]
239 public string Baz { get; set; }
241 public override object ProvideValue (IServiceProvider provider)
243 return "provided_value";
247 [TypeConverter (typeof (StringConverter))] // This attribute is the markable difference between MyExtension and this type.
248 public class MyExtension2 : MarkupExtension
250 public MyExtension2 ()
254 public MyExtension2 (Type arg1, string arg2)
260 [ConstructorArgument ("arg1")]
261 public Type Foo { get; set; }
263 [ConstructorArgument ("arg2")]
264 public string Bar { get; set; }
266 public override object ProvideValue (IServiceProvider provider)
268 return "provided_value";
272 [TypeConverter (typeof (StringConverter))] // same as MyExtension2 except that it is *not* MarkupExtension.
273 public class MyExtension3
275 public MyExtension3 ()
279 // cf. According to [MS-XAML-2009] 3.2.1.11, constructors are invalid unless the type is derived from TypeExtension. So, it is likely *ignored*.
280 public MyExtension3 (Type arg1, string arg2)
286 [ConstructorArgument ("arg1")]
287 public Type Foo { get; set; }
289 [ConstructorArgument ("arg2")]
290 public string Bar { get; set; }
293 [TypeConverter (typeof (DateTimeConverter))] // same as MyExtension3 except for the type converter.
294 public class MyExtension4
296 public MyExtension4 ()
300 // cf. According to [MS-XAML-2009] 3.2.1.11, constructors are invalid unless the type is derived from TypeExtension. So, it is likely *ignored*.
301 public MyExtension4 (Type arg1, string arg2)
307 [ConstructorArgument ("arg1")]
308 public Type Foo { get; set; }
310 [ConstructorArgument ("arg2")]
311 public string Bar { get; set; }
314 // no type converter, and there are only simple-type arguments == _PositionalParameters is applicable.
315 public class MyExtension5 : MarkupExtension
317 public MyExtension5 (string arg1, string arg2)
323 [ConstructorArgument ("arg1")]
324 public string Foo { get; set; }
326 [ConstructorArgument ("arg2")]
327 public string Bar { get; set; }
329 public override object ProvideValue (IServiceProvider sp)
335 // Almost the same as MyExtension5, BUT there is default constructor which XamlObjectReader prefers.
336 public class MyExtension6 : MarkupExtension
338 public MyExtension6 ()
342 public MyExtension6 (string arg1)
347 [ConstructorArgument ("arg1")]
348 public string Foo { get; set; }
350 public override object ProvideValue (IServiceProvider sp)
356 public class PositionalParametersClass1 : MarkupExtension
358 public PositionalParametersClass1 (string foo)
363 public PositionalParametersClass1 (string foo, int bar)
369 [ConstructorArgument ("foo")]
370 public string Foo { get; set; }
372 [ConstructorArgument ("bar")]
373 public int Bar { get; set; }
375 public override object ProvideValue (IServiceProvider sp)
381 public class PositionalParametersWrapper
383 public PositionalParametersClass1 Body { get; set; }
385 public PositionalParametersWrapper ()
389 public PositionalParametersWrapper (string foo, int bar)
391 Body = new PositionalParametersClass1 (foo, bar);
395 public class ListWrapper
397 public ListWrapper ()
399 Items = new List<int> ();
402 public ListWrapper (List<int> items)
407 public List<int> Items { get; private set; }
410 public class ListWrapper2
412 public ListWrapper2 ()
414 Items = new List<int> ();
417 public ListWrapper2 (List<int> items)
422 public List<int> Items { get; set; } // it is settable, which makes difference.
425 [ContentProperty ("Content")]
426 public class ContentIncludedClass
428 public string Content { get; set; }
431 public class StaticClass1
433 static StaticClass1 ()
438 public static string FooBar { get; set; }
441 public class StaticExtensionWrapper
443 public StaticExtensionWrapper ()
447 public StaticExtension Param { get; set; }
449 public static string Foo = "foo";
452 public class TypeExtensionWrapper
454 public TypeExtensionWrapper ()
458 public TypeExtension Param { get; set; }
461 public class XDataWrapper
463 public XData Markup { get; set; }
466 // FIXME: test it with XamlXmlReader (needs to create xml first)
467 public class EventContainer
469 public event Action Run;
472 public class NamedItem
476 References = new List<NamedItem> ();
479 public NamedItem (string name)
485 public string ItemName { get; set; }
486 public IList<NamedItem> References { get; private set; }
489 [RuntimeNameProperty ("ItemName")]
490 public class NamedItem2
494 References = new List<NamedItem2> ();
497 public NamedItem2 (string name)
503 public string ItemName { get; set; }
504 public IList<NamedItem2> References { get; private set; }
507 [TypeConverter (typeof (TestValueConverter))]
508 public class TestValueSerialized
510 public TestValueSerialized ()
514 public string Foo { get; set; }
517 public class TestValueConverter : TypeConverter
519 public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
521 //Console.Error.WriteLine ("### {0}:{1}", sourceType, context);
522 ValueSerializerContextTest.Context = (IValueSerializerContext) context;
526 public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object source)
528 //Console.Error.WriteLine ("##### {0}:{1}", source, context);
529 ValueSerializerContextTest.Provider = (IServiceProvider) context;
530 var sp = context as IServiceProvider;
531 // ValueSerializerContextTest.Context = (IValueSerializerContext) context; -> causes InvalidCastException
532 if ((source as string) == "v")
533 return new TestValueSerialized ();
534 throw new Exception ("huh");
537 public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType)
539 //Console.Error.WriteLine ("$$$ {0}:{1}", destinationType, context);
540 ValueSerializerContextTest.Context = (IValueSerializerContext) context;
541 return destinationType != typeof (MarkupExtension);
545 [ContentProperty ("Value")]
546 public class XmlSerializableWrapper
548 public XmlSerializableWrapper () // mandatory
549 : this (new XmlSerializable ())
553 public XmlSerializableWrapper (XmlSerializable val)
560 public XmlSerializable Value {
562 // To make it become XData, it cannot have a setter.
566 public class XmlSerializable : IXmlSerializable
568 public XmlSerializable ()
572 public XmlSerializable (string raw)
579 public string GetRaw ()
584 public void ReadXml (XmlReader reader)
586 reader.MoveToContent ();
587 raw = reader.ReadOuterXml ();
590 public void WriteXml (XmlWriter writer)
593 var xr = XmlReader.Create (new StringReader (raw));
595 writer.WriteNode (xr, false);
599 public XmlSchema GetSchema ()
605 public class Attachable
607 public static readonly AttachableMemberIdentifier FooIdentifier = new AttachableMemberIdentifier (typeof (Attachable), "Foo");
608 public static readonly AttachableMemberIdentifier ProtectedIdentifier = new AttachableMemberIdentifier (typeof (Attachable), "Protected");
610 public static string GetFoo (object target)
613 return AttachablePropertyServices.TryGetProperty (target, FooIdentifier, out v) ? v : null;
616 public static void SetFoo (object target, string value)
618 AttachablePropertyServices.SetProperty (target, FooIdentifier, value);
621 public static string GetBar (object target, object signatureMismatch)
626 public static void SetBar (object signatureMismatch)
630 public static void GetBaz (object noReturnType)
634 public static string SetBaz (object target, object extraReturnType)
639 protected static string GetProtected (object target)
642 return AttachablePropertyServices.TryGetProperty (target, ProtectedIdentifier, out v) ? v : null;
645 protected static void SetProtected (object target, string value)
647 AttachablePropertyServices.SetProperty (target, ProtectedIdentifier, value);
650 static Dictionary<object,List<EventHandler>> handlers = new Dictionary<object,List<EventHandler>> ();
652 public static void AddXHandler (object target, EventHandler handler)
654 List<EventHandler> l;
655 if (!handlers.TryGetValue (target, out l)) {
656 l = new List<EventHandler> ();
657 handlers [target] = l;
662 public static void RemoveXHandler (object target, EventHandler handler)
664 handlers [target].Remove (handler);
668 public class AttachedPropertyStore : IAttachedPropertyStore
670 public AttachedPropertyStore ()
674 Dictionary<AttachableMemberIdentifier,object> props = new Dictionary<AttachableMemberIdentifier,object> ();
676 public int PropertyCount {
677 get { return props.Count; }
680 public void CopyPropertiesTo (KeyValuePair<AttachableMemberIdentifier, object> [] array, int index)
682 ((ICollection<KeyValuePair<AttachableMemberIdentifier, object>>) props).CopyTo (array, index);
685 public bool RemoveProperty (AttachableMemberIdentifier attachableMemberIdentifier)
687 return props.Remove (attachableMemberIdentifier);
690 public void SetProperty (AttachableMemberIdentifier attachableMemberIdentifier, object value)
692 props [attachableMemberIdentifier] = value;
695 public bool TryGetProperty (AttachableMemberIdentifier attachableMemberIdentifier, out object value)
697 return props.TryGetValue (attachableMemberIdentifier, out value);
701 public class AttachedWrapper : AttachedPropertyStore
703 public AttachedWrapper ()
705 Value = new Attached ();
708 public Attached Value { get; set; }
711 public class AttachedWrapper2
713 public static readonly AttachableMemberIdentifier FooIdentifier = new AttachableMemberIdentifier (typeof (AttachedWrapper2), "Foo");
715 static AttachedPropertyStore store = new AttachedPropertyStore ();
717 public static string GetFoo (object target)
720 return store.TryGetProperty (FooIdentifier, out v) ? (string) v : null;
723 public static void SetFoo (object target, string value)
725 store.SetProperty (FooIdentifier, value);
728 public static int PropertyCount {
729 get { return store.PropertyCount; }
732 public AttachedWrapper2 ()
734 Value = new Attached ();
737 public Attached Value { get; set; }
740 public class Attached : Attachable
744 public class Attached2
746 internal String Property { get; set; }
749 public class AttachedWrapper3
751 public static void SetProperty (Attached2 a, string value)
757 public class EventStore
759 public bool Method1Invoked;
761 public event EventHandler<EventArgs> Event1;
762 public event Func<object> Event2;
764 public object Examine ()
767 Event1 (this, EventArgs.Empty);
774 public void Method1 ()
776 throw new Exception ();
779 public void Method1 (object o, EventArgs e)
781 Method1Invoked = true;
784 public object Method2 ()
790 public class EventStore2<TEventArgs> where TEventArgs : EventArgs
792 public bool Method1Invoked;
794 public event EventHandler<TEventArgs> Event1;
795 public event Func<object> Event2;
797 public object Examine ()
800 Event1 (this, default (TEventArgs));
807 public void Method1 ()
809 throw new Exception ();
812 public void Method1 (object o, EventArgs e)
814 throw new Exception ();
817 public void Method1 (object o, TEventArgs e)
819 Method1Invoked = true;
822 public object Method2 ()
828 public class AbstractContainer
830 public AbstractObject Value1 { get; set; }
831 public AbstractObject Value2 { get; set; }
834 public abstract class AbstractObject
836 public abstract string Foo { get; set; }
839 public class DerivedObject : AbstractObject
841 public override string Foo { get; set; }
844 public class ReadOnlyPropertyContainer
849 set { foo = Bar = value; }
851 public string Bar { get; private set; }
854 public class EnumContainer
856 public EnumValueType EnumProperty { get; set; }
859 public enum EnumValueType
867 [ContentProperty ("ListOfItems")]
868 public class CollectionContentProperty
870 public IList<SimpleClass> ListOfItems { get; set; }
872 public CollectionContentProperty ()
874 this.ListOfItems = new List<SimpleClass> ();
878 [ContentProperty ("ListOfItems")]
879 public class CollectionContentPropertyX
881 public IList ListOfItems { get; set; }
883 public CollectionContentPropertyX ()
885 this.ListOfItems = new List<IEnumerable> ();
889 public class SimpleClass
893 public class NullableContainer
895 public int? TestProp { get; set; }
898 public class DirectListContainer // for such xml that directly contains items in <*.Items> element.
900 public IList<DirectListContent> Items { get; set; }
902 public DirectListContainer ()
904 this.Items = new List<DirectListContent> ();
908 public class DirectListContent
910 public string Value { get; set; }
913 public class DirectDictionaryContainer // for such xml that directly contains items in <*.Items> element.
915 public IDictionary<EnumValueType,int> Items { get; set; }
917 public DirectDictionaryContainer ()
919 this.Items = new Dictionary<EnumValueType,int> ();
926 public class Configurations : List<Configuration>
928 private Configuration active;
929 private bool isFrozen;
931 public Configuration Active {
932 get { return this.active; }
935 throw new InvalidOperationException ("The 'Active' configuration can only be changed via modifying the source file (" + this.Source + ").");
942 public string Source { get; private set; }
945 public class Configuration
947 public string Version { get; set; }
949 public string Path { get; set; }
956 public class TypeOtherAssembly
958 [TypeConverter (typeof (NullableUintListConverter))]
959 public List<uint?> Values { get; set; }
961 public TypeOtherAssembly ()
963 this.Values = new List<uint?> ();
967 public class NullableUintListConverter : CustomTypeConverterBase
969 public override object ConvertFrom (System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
971 string configValue = value as string;
972 if (string.IsNullOrWhiteSpace (configValue))
975 string delimiterStr = ", ";
976 char [] delimiters = delimiterStr.ToCharArray ();
977 string [] tokens = configValue.Split (delimiters, StringSplitOptions.RemoveEmptyEntries);
979 List<uint?> parsedList = new List<uint?> (tokens.Length);
980 foreach (string token in tokens)
981 parsedList.Add(uint.Parse(token));
986 public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
988 var v = (List<uint?>) value;
989 return String.Join (", ", (from i in v select i.ToString ()).ToArray ());
993 public class CustomTypeConverterBase : TypeConverter
995 public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
997 if (sourceType == typeof (string))
1001 return base.CanConvertFrom (context, sourceType);
1007 [MarkupExtensionReturnType (typeof (object))]
1008 public class ResourceExtension : MarkupExtension
1010 [ConstructorArgument ("key")]
1011 public object Key { get; set; }
1013 public ResourceExtension (object key)
1018 public override object ProvideValue (IServiceProvider serviceProvider)
1020 IXamlSchemaContextProvider service = serviceProvider.GetService (typeof (IXamlSchemaContextProvider)) as IXamlSchemaContextProvider;
1021 IAmbientProvider provider = serviceProvider.GetService (typeof (IAmbientProvider)) as IAmbientProvider;
1022 Debug.Assert (provider != null, "The provider should not be null!");
1024 XamlSchemaContext schemaContext = service.SchemaContext;
1025 XamlType[] types = new XamlType [] { schemaContext.GetXamlType (typeof (ResourcesDict)) };
1027 // ResourceDict is marked as Ambient, so the instance current being deserialized should be in this list.
1028 List<AmbientPropertyValue> list = provider.GetAllAmbientValues (null, false, types) as List<AmbientPropertyValue>;
1029 if (list.Count != 1)
1030 throw new Exception ("expected ambient property count == 1 but " + list.Count);
1031 for (int i = 0; i < list.Count; i++) {
1032 AmbientPropertyValue value = list [i];
1033 ResourcesDict dict = value.Value as ResourcesDict;
1035 // For this example, we know that dict should not be null and that it is the only value in list.
1036 object result = dict [this.Key];
1044 [UsableDuringInitialization (true), Ambient]
1045 public class ResourcesDict : Dictionary<object, object>
1049 public class TestObject
1051 public TestObject TestProperty { get; set; }
1056 public class ResourcesDict2 : Dictionary<object, object>
1060 public class TestObject2
1062 public string TestProperty { get; set; }
1066 [ContentProperty ("Items")]
1067 public class SimpleType
1069 public IList<SimpleType> Items { get; set; }
1071 public IList<SimpleType> NonContentItems { get; set; }
1073 public string TestProperty { get; set; }
1075 public SimpleType ()
1077 this.Items = new List<SimpleType> ();
1078 this.NonContentItems=new List<SimpleType> ();
1082 public class ContentPropertyContainer : Dictionary<object, object>
1088 #region "xamarin bug #2927"
1089 namespace XamarinBug2927
1091 public class RootClass
1095 Child = new MyChildClass ();
1098 public bool Invoked;
1100 public ChildClass Child { get; set; }
1103 public class MyRootClass : RootClass
1105 public void HandleMyEvent (object sender, EventArgs e)
1111 public class RootClass2
1113 public RootClass2 ()
1115 Child = new MyChildClass ();
1118 public bool Invoked;
1120 public ChildClass Child { get; set; }
1122 public void HandleMyEvent (object sender, EventArgs e)
1128 public class MyRootClass2 : RootClass2
1132 public class ChildClass
1134 public bool Invoked;
1136 public DescendantClass Descendant { get; set; }
1139 public class MyChildClass : ChildClass
1141 public MyChildClass ()
1143 Descendant = new DescendantClass () { Value = "x" };
1146 public void HandleMyEvent (object sender, EventArgs e)
1152 public class DescendantClass
1154 public bool Invoked;
1155 public event EventHandler DoWork;
1156 public string Value { get; set; }
1160 DoWork (this, EventArgs.Empty);
1163 public void HandleMyEvent (object sender, EventArgs e)
1171 #region "xamarin bug 3003"
1173 namespace XamarinBug3003
1175 public static class TestContext
1177 public static StringWriter Writer = new StringWriter ();
1179 public const string XmlInput = @"<Parent xmlns='http://schemas.example.com/test' Title='Parent Title'>
1180 <Child Parent.AssociatedProperty='child 1' Title='Child Title 1'></Child>
1181 <Child Parent.AssociatedProperty='child 2' Title='Child Title 2'></Child>
1184 // In bug #3003 repro, there is output "Item 'Child' inserted at index 'x'" , but I couldn't get it in the output either on .NET or Mono.
1185 // On the other hand, in the standalone repro case they are in the output either in mono or in .NET. So I just stopped caring about that as it works as expected.
1186 public const string ExpectedResult = @"
1188 ISupportInitialize.BeginInit: Parent
1189 XamlObjectWriterSettings.AfterBeginInit: Parent
1190 XamlObjectWriterSettings.BeforeProperties: Parent
1191 XamlObjectWriterSettings.XamlSetValue: Parent Title, Member: Title
1192 Parent.Title_set: Parent
1194 ISupportInitialize.BeginInit: Child
1195 XamlObjectWriterSettings.AfterBeginInit: Child
1196 XamlObjectWriterSettings.BeforeProperties: Child
1197 XamlObjectWriterSettings.XamlSetValue: child 1, Member: AssociatedProperty
1198 Parent.SetAssociatedProperty: child 1
1199 XamlObjectWriterSettings.XamlSetValue: Child Title 1, Member: Title
1200 Child.Title_set: Child
1201 XamlObjectWriterSettings.AfterProperties: Child
1202 ISupportInitialize.EndInit: Child
1203 XamlObjectWriterSettings.AfterEndInit: Child
1205 ISupportInitialize.BeginInit: Child
1206 XamlObjectWriterSettings.AfterBeginInit: Child
1207 XamlObjectWriterSettings.BeforeProperties: Child
1208 XamlObjectWriterSettings.XamlSetValue: child 2, Member: AssociatedProperty
1209 Parent.SetAssociatedProperty: child 2
1210 XamlObjectWriterSettings.XamlSetValue: Child Title 2, Member: Title
1211 Child.Title_set: Child
1212 XamlObjectWriterSettings.AfterProperties: Child
1213 ISupportInitialize.EndInit: Child
1214 XamlObjectWriterSettings.AfterEndInit: Child
1215 XamlObjectWriterSettings.AfterProperties: Parent
1216 ISupportInitialize.EndInit: Parent
1217 XamlObjectWriterSettings.AfterEndInit: Parent
1222 public class BaseItemCollection : Collection<BaseItem>
1224 protected override void InsertItem (int index, BaseItem item)
1226 base.InsertItem (index, item);
1227 Console.WriteLine ("Item '{0}' inserted at index '{1}'", item, index);
1231 public class BaseItem : ISupportInitialize
1233 Dictionary<string, object> properties = new Dictionary<string, object> ();
1235 public Dictionary<string, object> Properties
1237 get { return properties; }
1244 get { return title; }
1248 TestContext.Writer.WriteLine ("{0}.Title_set: {0}", this.GetType ().Name, value);
1254 TestContext.Writer.WriteLine ("{0} Constructed", this.GetType ().Name);
1258 public void BeginInit ()
1260 TestContext.Writer.WriteLine ("ISupportInitialize.BeginInit: {0}", this);
1263 public void EndInit ()
1265 TestContext.Writer.WriteLine ("ISupportInitialize.EndInit: {0}", this);
1268 public override string ToString ()
1270 return this.GetType ().Name.ToString ();
1274 public class Child : BaseItem
1278 [ContentProperty ("Children")]
1279 public class Parent : BaseItem
1281 BaseItemCollection children = new BaseItemCollection ();
1283 public BaseItemCollection Children
1285 get { return children; }
1289 public static string GetAssociatedProperty (Child child)
1292 if (child.Properties.TryGetValue ("myassociatedproperty", out value)) return value as string;
1296 public static void SetAssociatedProperty (Child child, string value)
1298 TestContext.Writer.WriteLine ("Parent.SetAssociatedProperty: {0}", value);
1299 child.Properties ["myassociatedproperty"] = value;