2 // ManagedXamlLoader.cs
5 // Moonlight List (moonlight-list@lists.ximian.com)
7 // Copyright 2007 Novell, Inc.
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System
.Collections
;
31 using System
.Diagnostics
;
32 using System
.Reflection
;
33 using System
.Collections
.Generic
;
36 using System
.Windows
.Controls
;
37 using System
.Windows
.Markup
;
38 using System
.Runtime
.InteropServices
;
39 using System
.ComponentModel
;
40 using System
.Windows
.Data
;
41 using System
.Text
.RegularExpressions
;
46 internal sealed class ManagedXamlLoader
: XamlLoader
{
49 XamlLoaderCallbacks callbacks
;
52 public ManagedXamlLoader ()
56 public ManagedXamlLoader (Assembly assembly
, string resourceBase
, IntPtr surface
, IntPtr plugin
) : base (resourceBase
, surface
, plugin
)
58 this.assembly
= assembly
;
61 public override void Setup (IntPtr native_loader
, IntPtr plugin
, IntPtr surface
, string filename
, string contents
)
63 base.Setup (native_loader
, plugin
, surface
, filename
, contents
);
66 // Registers callbacks that are invoked from the
70 callbacks
.lookup_object
= new LookupObjectCallback (cb_lookup_object
);
71 callbacks
.create_gchandle
= new CreateGCHandleCallback (cb_create_gchandle
);
72 callbacks
.set_property
= new SetPropertyCallback (cb_set_property
);
73 callbacks
.import_xaml_xmlns
= new ImportXamlNamespaceCallback (cb_import_xaml_xmlns
);
74 callbacks
.get_content_property_name
= new GetContentPropertyNameCallback (cb_get_content_property_name
);
75 callbacks
.add_child
= new AddChildCallback (cb_add_child
);
78 NativeMethods
.xaml_loader_set_callbacks (native_loader
, callbacks
);
80 if (plugin
!= IntPtr
.Zero
)
81 System
.Windows
.Interop
.PluginHost
.SetPluginHandle (plugin
);
83 if (!AllowMultipleSurfacesPerDomain
) {
84 PluginInDomain
= plugin
;
85 SurfaceInDomain
= surface
;
90 // Creates a managed dependency object from the xaml.
92 public override object CreateObjectFromString (string xaml
, bool createNamescope
)
94 return CreateObjectFromString (xaml
, createNamescope
, false);
97 public override object CreateObjectFromString (string xaml
, bool createNamescope
, bool validateTemplates
)
100 throw new ArgumentNullException ("xaml");
106 DependencyObject
.Initialize ();
108 top
= CreateFromString (xaml
, createNamescope
, validateTemplates
, out kind
);
110 if (top
== IntPtr
.Zero
)
113 result
= Value
.ToObject (null, top
);
114 DependencyObject dob
= result
as DependencyObject
;
116 NativeMethods
.event_object_unref (dob
.native
);
123 // Creates a managed dependency object from the xaml in the file
125 public override object CreateObjectFromFile (string file
, bool createNamescope
)
128 throw new ArgumentNullException ("file");
134 DependencyObject
.Initialize ();
136 top
= CreateFromFile (file
, createNamescope
, out kind
);
138 if (top
== IntPtr
.Zero
)
141 result
= Value
.ToObject (null, top
);
142 DependencyObject dob
= result
as DependencyObject
;
144 NativeMethods
.event_object_unref (dob
.native
);
151 // Tries to load the assembly.
153 public AssemblyLoadResult
LoadAssembly (string asm_name
, out Assembly clientlib
)
157 clientlib
= Application
.GetAssembly (asm_name
);
158 return clientlib
!= null ? AssemblyLoadResult
.Success
: AssemblyLoadResult
.MissingAssembly
;
161 private unsafe bool TryGetDefaultAssemblyName (Value
* top_level
, out string assembly_name
)
163 if (assembly
!= null) {
164 assembly_name
= assembly
.GetName ().Name
;
168 object obj
= Value
.ToObject (null, top_level
);
171 assembly_name
= null;
175 assembly_name
= obj
.GetType ().Assembly
.GetName ().Name
;
179 private unsafe bool LookupObject (Value
*top_level
, Value
*parent
, string xmlns
, string name
, bool create
, bool is_property
, out Value
value)
182 throw new ArgumentNullException ("type_name");
186 int dot
= name
.IndexOf ('.');
187 return LookupPropertyObject (top_level
, parent
, xmlns
, name
, dot
, create
, out value);
190 if (top_level
== null && xmlns
== null) {
191 return LookupComponentFromName (top_level
, name
, create
, out value);
194 string assembly_name
= AssemblyNameFromXmlns (xmlns
);
195 string clr_namespace
= ClrNamespaceFromXmlns (xmlns
);
196 string full_name
= string.IsNullOrEmpty (clr_namespace
) ? name
: clr_namespace
+ "." + name
;
198 Type type
= LookupType (top_level
, assembly_name
, full_name
);
200 Console
.Error
.WriteLine ("ManagedXamlLoader::LookupObject: GetType ({0}) failed using assembly: {1} ({2}, {3}).", name
, assembly_name
, xmlns
, full_name
);
207 if (!type
.IsPublic
) {
209 throw new XamlParseException ("Attempting to create a private type");
214 res
= Activator
.CreateInstance (type
);
215 } catch (TargetInvocationException ex
) {
216 Console
.WriteLine (ex
);
217 Console
.Error
.WriteLine ("ManagedXamlLoader::LookupObject: CreateInstance ({0}) failed: {1}", name
, ex
.InnerException
);
223 Console
.Error
.WriteLine ("ManagedXamlLoader::LookupObject ({0}, {1}, {2}): unable to create object instance: '{3}', the object was of type '{4}'",
224 assembly_name
, xmlns
, name
, full_name
, type
.FullName
);
228 value = Value
.FromObject (res
, false);
231 value.k
= Deployment
.Current
.Types
.Find (type
).native_handle
;
237 private unsafe bool LookupPropertyObject (Value
* top_level
, Value
* parent_value
, string xmlns
, string name
, int dot
, bool create
, out Value
value)
239 string prop_name
= name
.Substring (dot
+ 1);
240 object parent
= Value
.ToObject (null, parent_value
);
242 if (parent
== null) {
247 PropertyInfo pi
= null;
248 bool is_attached
= true;
249 string type_name
= name
.Substring (0, dot
);
251 Type t
= parent
.GetType ();
252 while (t
!= typeof (object)) {
253 if (t
.Name
== type_name
) {
261 string full_type_name
= type_name
;
263 string ns
= ClrNamespaceFromXmlns (xmlns
);
264 full_type_name
= String
.Concat (ns
, ".", type_name
);
267 MethodInfo set_method
= GetSetMethodForAttachedProperty (top_level
, xmlns
, type_name
, full_type_name
, prop_name
);
269 ParameterInfo
[] set_params
= set_method
.GetParameters ();
270 if (set_params
== null || set_params
.Length
< 2) {
272 Console
.Error
.WriteLine ("set method signature is incorrect.");
276 ManagedType mt
= Deployment
.Current
.Types
.Find (set_params
[1].ParameterType
);
279 value.k
= mt
.native_handle
;
283 pi
= parent
.GetType ().GetProperty (name
.Substring (dot
+ 1), BindingFlags
.Instance
| BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.FlattenHierarchy
);
290 ManagedType mt
= Deployment
.Current
.Types
.Find (pi
.PropertyType
);
292 value.k
= mt
.native_handle
;
299 private unsafe bool LookupComponentFromName (Value
* top_level
, string name
, bool create
, out Value
value)
302 Type type
= Application
.GetComponentTypeFromName (name
);
308 value.k
= Deployment
.Current
.Types
.Find (type
).native_handle
;
312 object obj
= Application
.CreateComponentFromName (name
);
318 value = Value
.FromObject (obj
, false);
322 private static bool IsAttachedProperty (string name
)
324 return name
.IndexOf ('.') > 0;
327 private unsafe bool IsAttachedProperty (XamlCallbackData
*data
, object target
, string xmlns
, string prop_xmlns
, string name
)
329 string type_name
= null;
330 string full_type_name
= null;
332 name
= GetNameForAttachedProperty (xmlns
, prop_xmlns
, name
, out type_name
, out full_type_name
);
337 MethodInfo set_method
= GetSetMethodForAttachedProperty (data
->top_level
, prop_xmlns
, type_name
, full_type_name
, name
);
338 if (set_method
== null)
341 return !target
.GetType ().IsSubclassOf (set_method
.DeclaringType
);
344 private unsafe DependencyProperty
LookupDependencyPropertyForBinding (XamlCallbackData
*data
, FrameworkElement fwe
, string type_name
, string propertyName
)
346 // map the property name + type_name to an actual DependencyProperty
348 Type type
= string.IsNullOrEmpty (type_name
) ? null : TypeFromString (data
, type_name
);
351 kind
= Deployment
.Current
.Types
.TypeToNativeKind (type
);
353 kind
= fwe
.GetKind ();
356 if (kind
== Kind
.INVALID
)
360 return DependencyProperty
.Lookup (kind
, propertyName
);
368 private unsafe bool TrySetExpression (XamlCallbackData
*data
, string xmlns
, object target
, IntPtr target_data
, Value
* target_parent_ptr
, string type_name
, string prop_xmlns
, string name
, string full_name
, Value
* value_ptr
, IntPtr value_data
)
370 FrameworkElement dob
= target
as FrameworkElement
;
371 object obj_value
= Value
.ToObject (null, value_ptr
);
372 string str_value
= obj_value
as string;
374 if (str_value
== null)
377 if (!str_value
.StartsWith ("{"))
380 MarkupExpressionParser p
= new MarkupExpressionParser (target
, name
, data
->parser
, target_data
);
381 string expression
= str_value
;
382 object o
= p
.ParseExpression (ref expression
);
389 Binding binding
= o
as Binding
;
390 DependencyProperty prop
= null;
393 string full_type_name
= type_name
;
394 if (IsAttachedProperty (full_name
))
395 GetNameForAttachedProperty (xmlns
, prop_xmlns
, full_name
, out type_name
, out full_type_name
);
396 prop
= LookupDependencyPropertyForBinding (data
, dob
, full_type_name
, name
);
402 dob
.SetBinding (prop
, binding
);
405 else if (o
is TemplateBindingExpression
) {
406 // Applying a {TemplateBinding} to a DO which is not a FrameworkElement should silently discard
411 TemplateBindingExpression tb
= o
as TemplateBindingExpression
;
413 IntPtr context
= NativeMethods
.xaml_loader_get_context (data
->loader
);
414 IntPtr source_ptr
= NativeMethods
.xaml_context_get_template_binding_source (context
);
416 DependencyObject templateSourceObject
= NativeDependencyObjectHelper
.FromIntPtr (source_ptr
) as DependencyObject
;
418 if (templateSourceObject
== null)
421 DependencyProperty sourceProperty
= DependencyProperty
.Lookup (templateSourceObject
.GetKind(),
422 tb
.SourcePropertyName
);
423 if (sourceProperty
== null)
426 DependencyProperty prop
= null;
429 prop
= LookupDependencyPropertyForBinding (data
, dob
, type_name
, name
);
434 tb
.TargetProperty
= prop
;
435 tb
.Source
= templateSourceObject
as Control
;
436 tb
.SourceProperty
= sourceProperty
;
438 dob
.SetTemplateBinding (prop
, tb
);
443 // static resources fall into this
446 DependencyProperty prop
= LookupDependencyPropertyForBinding (data
, dob
, type_name
, name
);
450 o
= ConvertType (null, prop
.PropertyType
, o
);
451 dob
.SetValue (prop
, o
);
453 if (IsAttachedProperty (full_name
))
454 return TrySetAttachedProperty (data
, xmlns
, target
, target_data
, prop_xmlns
, full_name
, o
);
456 PropertyInfo pi
= target
.GetType ().GetProperty (name
, BindingFlags
.Instance
| BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.FlattenHierarchy
);
458 o
= ConvertType (null, pi
.PropertyType
, o
);
459 SetValue (data
, target_data
, pi
, target
, o
);
467 private string GetNameForAttachedProperty (string xmlns
, string prop_xmlns
, string name
, out string type_name
, out string full_type_name
)
469 int dot
= name
.IndexOf ('.');
472 type_name
= name
.Substring (0, dot
);
473 full_type_name
= type_name
;
474 if (prop_xmlns
!= null || xmlns
!= null) {
475 string ns
= ClrNamespaceFromXmlns (prop_xmlns
== null ? xmlns
: prop_xmlns
);
477 full_type_name
= String
.Concat (ns
, ".", type_name
);
479 name
= name
.Substring (++dot
, name
.Length
- dot
);
481 full_type_name
= null;
489 private unsafe bool TrySetAttachedProperty (XamlCallbackData
*data
, string xmlns
, object target
, IntPtr target_data
, string prop_xmlns
, string name
, Value
* value_ptr
)
491 string full_name
= name
;
492 string type_name
= null;
493 string full_type_name
= null;
495 name
= GetNameForAttachedProperty (xmlns
, prop_xmlns
, name
, out type_name
, out full_type_name
);
501 object o_value
= GetObjectValue (target
, target_data
, name
, data
->parser
, value_ptr
, out error
);
503 return TrySetAttachedProperty (data
, xmlns
, target
, target_data
, prop_xmlns
, full_name
, o_value
);
506 private unsafe bool TrySetAttachedProperty (XamlCallbackData
*data
, string xmlns
, object target
, IntPtr target_data
, string prop_xmlns
, string name
, object o_value
)
508 string type_name
= null;
509 string full_type_name
= null;
511 name
= GetNameForAttachedProperty (xmlns
, prop_xmlns
, name
, out type_name
, out full_type_name
);
516 MethodInfo set_method
= GetSetMethodForAttachedProperty (data
->top_level
, prop_xmlns
, type_name
, full_type_name
, name
);
517 if (set_method
== null) {
518 Console
.Error
.WriteLine ("set method is null: {0} {1}", String
.Concat ("Set", name
), prop_xmlns
);
522 ParameterInfo
[] set_params
= set_method
.GetParameters ();
523 if (set_params
== null || set_params
.Length
< 2) {
524 Console
.Error
.WriteLine ("set method signature is incorrect.");
528 MethodInfo get_method
= set_method
.DeclaringType
.GetMethod (String
.Concat ("Get", name
), BindingFlags
.Static
| BindingFlags
.Public
| BindingFlags
.NonPublic
);
531 // The Setter might actually want a collection, in this case we grab the old collection with the getter
532 // and then add the new object to the collection
534 // TODO: Check if the setter method still gets called on Silverlight
535 if (typeof (IList
).IsAssignableFrom (set_params
[1].ParameterType
) && !(o_value
is IList
)) {
537 if (get_method
!= null || get_method
.GetParameters () == null || get_method
.GetParameters ().Length
!= 1) {
538 IList the_list
= (IList
) get_method
.Invoke (null, new object [] { target }
);
540 if (the_list
== null) {
541 the_list
= (IList
) Activator
.CreateInstance (set_params
[1].ParameterType
);
542 if (the_list
== null)
544 set_method
.Invoke (null, new object [] {target, the_list}
);
548 the_list
.Add (o_value
);
550 if (o_value
is DependencyObject
&& target
is DependencyObject
&& !(the_list
is DependencyObject
)) {
551 NativeMethods
.dependency_object_set_parent_safe (((DependencyObject
)o_value
).native
, ((DependencyObject
)target
).native
);
557 // don't return here, fall through to the ConvertType case below.
560 // I guess we need to wrap the current value in a collection, or does this error out?
561 Console
.WriteLine ("ow god my eye!");
566 o_value
= ConvertType (get_method
, set_params
[1].ParameterType
, o_value
);
567 set_method
.Invoke (null, new object [] {target, o_value}
);
571 private unsafe bool TrySetPropertyReflection (XamlCallbackData
*data
, string xmlns
, object target
, IntPtr target_data
, Value
* target_parent_ptr
, string type_name
, string name
, Value
* value_ptr
, IntPtr value_data
, out string error
)
573 PropertyInfo pi
= target
.GetType ().GetProperty (name
, BindingFlags
.Instance
| BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.FlattenHierarchy
);
576 error
= "Property does not exist.";
580 if (!SetPropertyFromValue (data
, target
, target_data
, target_parent_ptr
, pi
, value_ptr
, value_data
, out error
))
587 private unsafe bool TrySetEventReflection (XamlCallbackData
*data
, string xmlns
, object publisher
, string type_name
, string name
, Value
* value_ptr
, out string error
)
589 object subscriber
= null;
590 EventInfo ie
= publisher
.GetType ().GetEvent (name
);
591 string handler_name
= Value
.ToObject (null, value_ptr
) as string;
594 subscriber
= Value
.ToObject (null, data
->top_level
);
599 //Console.WriteLine ("TrySetEventReflection ({0}, {1}, {2}, {3}, {4}, {5}) handler_name: {6}", data->top_level, xmlns, publisher, type_name, name, value_ptr, handler_name);
602 error
= "Event does not exist.";
607 if (handler_name
== null) {
608 error
= "No method name supplied for event handler.";
612 MethodInfo invoker_info
= ie
.EventHandlerType
.GetMethod ("Invoke");
613 ParameterInfo
[] event_params
= invoker_info
.GetParameters ();
616 Type stype
= subscriber
.GetType ();
617 MethodInfo
[] methods
= stype
.GetMethods (BindingFlags
.Public
| BindingFlags
.NonPublic
| BindingFlags
.DeclaredOnly
| BindingFlags
.Instance
);
618 MethodInfo candidate
= null;
619 bool name_match
= false;
621 for (int i
= 0; i
< methods
.Length
; i
++) {
622 MethodInfo m
= methods
[i
];
623 ParameterInfo
[] parameters
;
625 if (m
.Name
!= handler_name
)
629 error
= "Multiple candidates with the same name found for event handler.";
630 // Console.WriteLine (error);
636 if (m
.ReturnType
!= typeof (void))
639 parameters
= m
.GetParameters ();
641 if (parameters
.Length
!= event_params
.Length
)
645 for (int p
= 0; p
< parameters
.Length
; p
++) {
646 if (!event_params
[p
].ParameterType
.IsSubclassOf (parameters
[p
].ParameterType
) && parameters
[p
].ParameterType
!= event_params
[p
].ParameterType
) {
647 Console
.WriteLine ("mismatch: {0} and {1}", parameters
[p
].ParameterType
, event_params
[p
].ParameterType
);
656 if (candidate
!= null) {
657 error
= "Multiple candidates for event handler found.";
658 // Console.WriteLine (error);
665 if (candidate
== null) {
666 error
= "Event handler not found.";
667 // Console.WriteLine (error);
671 d
= Delegate
.CreateDelegate (ie
.EventHandlerType
, subscriber
, candidate
, false);
674 Console
.Error
.WriteLine ("ManagedXamlLoader::HookupEvent ({0}, {1}, {2}): unable to create delegate (src={3} target={4}).", (IntPtr
) data
->top_level
, name
, (IntPtr
)value_ptr
, ie
.EventHandlerType
, publisher
);
675 error
= "Can not create even delegate.";
679 // Console.Error.WriteLine ("ManagedXamlLoader::HookupEvent ({0}, {1}, {2}): Successfully created delegate (src={3} target={4}).", (IntPtr) data->top_level, name, value_ptr, ie.EventHandlerType, publisher);
682 ie
.AddEventHandler (publisher
, d
);
686 private unsafe bool TrySetEnumContentProperty (XamlCallbackData
*data
, string xmlns
, object target
, Value
* target_ptr
, IntPtr target_data
, Value
* value_ptr
, IntPtr value_data
)
688 object obj_value
= Value
.ToObject (null, value_ptr
);
689 string str_value
= obj_value
as string;
691 if (str_value
== null)
694 string assembly_name
= AssemblyNameFromXmlns (xmlns
);
695 string clr_namespace
= ClrNamespaceFromXmlns (xmlns
);
696 string type_name
= NativeMethods
.xaml_get_element_name (data
->parser
, target_data
);
697 string full_name
= String
.IsNullOrEmpty (clr_namespace
) ? type_name
: clr_namespace
+ "." + type_name
;
699 Type type
= LookupType (data
->top_level
, assembly_name
, full_name
);
701 if (type
== null || !type
.IsEnum
)
704 object e
= Enum
.Parse (type
, str_value
, true);
706 NativeMethods
.value_free_value2 ((IntPtr
)target_ptr
);
709 Value
*val
= (Value
*) target_ptr
;
711 GCHandle handle
= GCHandle
.Alloc (e
);
712 val
->k
= Kind
.MANAGED
;
713 val
->u
.p
= GCHandle
.ToIntPtr (handle
);
719 private unsafe bool TrySetCollectionContentProperty (string xmlns
, object target
, Value
* target_ptr
, IntPtr target_data
, Value
* value_ptr
, IntPtr value_data
)
721 IList list
= target
as IList
;
726 object value = Value
.ToObject (null, value_ptr
);
732 private unsafe bool TrySetObjectTextProperty (XamlCallbackData
*data
, string xmlns
, object target
, Value
* target_ptr
, IntPtr target_data
, Value
* value_ptr
, IntPtr value_data
)
734 object obj_value
= Value
.ToObject (null, value_ptr
);
735 string str_value
= obj_value
as string;
737 if (str_value
== null)
740 string assembly_name
= AssemblyNameFromXmlns (xmlns
);
741 string clr_namespace
= ClrNamespaceFromXmlns (xmlns
);
742 string type_name
= NativeMethods
.xaml_get_element_name (data
->parser
, target_data
);
743 string full_name
= String
.IsNullOrEmpty (clr_namespace
) ? type_name
: clr_namespace
+ "." + type_name
;
745 Type type
= LookupType (data
->top_level
, assembly_name
, full_name
);
747 if (type
== null || type
.IsSubclassOf (typeof (DependencyObject
)))
750 // For now just trim the string right here, in the future this should probably be done in the xaml parser
751 object e
= ConvertType (null, type
, str_value
.Trim ());
753 NativeMethods
.value_free_value2 ((IntPtr
)target_ptr
);
756 Value
*val
= (Value
*) target_ptr
;
758 GCHandle handle
= GCHandle
.Alloc (e
);
759 val
->k
= Kind
.MANAGED
;
760 val
->u
.p
= GCHandle
.ToIntPtr (handle
);
766 private unsafe bool SetProperty (XamlCallbackData
*data
, string xmlns
, Value
* target_ptr
, IntPtr target_data
, Value
* target_parent_ptr
, string prop_xmlns
, string name
, Value
* value_ptr
, IntPtr value_data
)
769 object target
= Value
.ToObject (null, target_ptr
);
771 if (target
== null) {
772 Console
.Error
.WriteLine ("target is null: {0} {1} {2}", (IntPtr
)target_ptr
, name
, xmlns
);
777 if (TrySetEnumContentProperty (data
, xmlns
, target
, target_ptr
, target_data
, value_ptr
, value_data
))
779 if (TrySetCollectionContentProperty (xmlns
, target
, target_ptr
, target_data
, value_ptr
, value_data
))
781 if (TrySetObjectTextProperty (data
, xmlns
, target
, target_ptr
, target_data
, value_ptr
, value_data
))
783 Console
.Error
.WriteLine ("no property name supplied");
787 string full_name
= name
;
788 int dot
= name
.IndexOf ('.');
789 string type_name
= null;
792 type_name
= name
.Substring (0, dot
);
794 string ns
= ClrNamespaceFromXmlns (xmlns
);
796 type_name
= String
.Concat (ns
, ".", type_name
);
798 name
= name
.Substring (++dot
, name
.Length
- dot
);
801 if (TrySetExpression (data
, xmlns
, target
, target_data
, target_parent_ptr
, type_name
, prop_xmlns
, name
, full_name
, value_ptr
, value_data
))
804 if (!IsAttachedProperty (data
, target
, xmlns
, prop_xmlns
, full_name
)) {
805 if (TrySetPropertyReflection (data
, xmlns
, target
, target_data
, target_parent_ptr
, type_name
, name
, value_ptr
, value_data
, out error
))
808 if (TrySetEventReflection (data
, xmlns
, target
, type_name
, name
, value_ptr
, out error
))
811 if (TrySetAttachedProperty (data
, xmlns
, target
, target_data
, prop_xmlns
, full_name
, value_ptr
))
819 private unsafe bool AddChild (XamlCallbackData
*data
, Value
* parent_parent_ptr
, bool parent_is_property
, string parent_xmlns
, Value
*parent_ptr
, IntPtr parent_data
, Value
* child_ptr
, IntPtr child_data
)
821 object parent_parent
= Value
.ToObject (null, parent_parent_ptr
);
822 object parent
= Value
.ToObject (null, parent_ptr
);
823 object child
= Value
.ToObject (null, child_ptr
);
825 if (parent_is_property
)
826 return AddChildToProperty (data
, parent_parent
, parent_xmlns
, parent
, child
, child_data
);
828 return AddChildToItem (data
, parent_parent_ptr
, parent
, parent_data
, child_ptr
, child
, child_data
);
831 private unsafe bool AddChildToProperty (XamlCallbackData
*data
, object parent_parent
, string parent_xmlns
, object parent
, object child
, IntPtr child_data
)
833 string full_prop_name
= parent
as string;
835 if (full_prop_name
== null) {
836 Console
.Error
.WriteLine ("Attempting to add child to non string parent {0} as a property.", parent
);
841 int dot
= full_prop_name
.IndexOf ('.');
844 string type_name
= full_prop_name
.Substring (0, dot
);
845 string prop_name
= full_prop_name
.Substring (++dot
, full_prop_name
.Length
- dot
);
847 Type target_type
= TypeFromString (data
, parent_xmlns
, type_name
);
849 if (target_type
== null) {
850 Console
.Error
.WriteLine ("Type '{0}' with xmlns '{1}' could not be found", type_name
, parent_xmlns
);
854 if (!target_type
.IsAssignableFrom (parent_parent
.GetType ())) {
855 // This would happen with an attached property, we don't need to do anything here....do we?
859 PropertyInfo pi
= parent_parent
.GetType ().GetProperty (prop_name
, BindingFlags
.Instance
| BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.FlattenHierarchy
);
862 Console
.Error
.WriteLine ("Property does not exist. {0}", prop_name
);
866 if (typeof (ResourceDictionary
).IsAssignableFrom (pi
.PropertyType
) && !(child
is ResourceDictionary
)) {
867 ResourceDictionary the_dict
= (ResourceDictionary
) pi
.GetValue (parent_parent
, null);
868 string key_name
= NativeMethods
.xaml_get_element_key (data
->parser
, child_data
);
870 if (key_name
== null) {
871 throw new XamlParseException (2034, "Elements in a ResourceDictionary must have x:Key or x:Name attribute.");
874 if (the_dict
== null) {
875 the_dict
= (ResourceDictionary
) Activator
.CreateInstance (pi
.PropertyType
);
876 if (the_dict
== null) {
877 Console
.Error
.WriteLine ("Unable to create instance of dictionary: " + pi
.PropertyType
);
880 pi
.SetValue (parent_parent
, the_dict
, null);
884 the_dict
.Add (key_name
, child
);
885 if (child
is DependencyObject
&& parent_parent
is DependencyObject
&& !(the_dict
is DependencyObject
)) {
886 NativeMethods
.dependency_object_set_parent_safe (((DependencyObject
) child
).native
, ((DependencyObject
) parent_parent
).native
);
890 } catch (ArgumentException
) {
891 throw new XamlParseException (2273, "Elements in the same ResourceDictionary cannot have the same x:Key");
895 if (typeof (IList
).IsAssignableFrom (pi
.PropertyType
) && !(child
is IList
)) {
896 IList the_list
= (IList
) pi
.GetValue (parent_parent
, null);
898 if (the_list
== null) {
899 the_list
= (IList
) Activator
.CreateInstance (pi
.PropertyType
);
900 if (the_list
== null) {
901 Console
.Error
.WriteLine ("Unable to create instance of list: " + pi
.PropertyType
);
904 pi
.SetValue (parent_parent
, the_list
, null);
908 the_list
.Add (child
);
910 if (child
is DependencyObject
&& parent_parent
is DependencyObject
&& !(the_list
is DependencyObject
)) {
911 NativeMethods
.dependency_object_set_parent_safe (((DependencyObject
)child
).native
, ((DependencyObject
)parent_parent
).native
);
916 catch (Exception e
) {
917 Console
.WriteLine (e
);
925 private unsafe bool AddChildToItem (XamlCallbackData
*data
, Value
*parent_parent_ptr
, object parent
, IntPtr parent_data
, Value
*child_ptr
, object child
, IntPtr child_data
)
927 ResourceDictionary the_dict
= parent
as ResourceDictionary
;
928 if (the_dict
!= null) {
929 string key_name
= NativeMethods
.xaml_get_element_key (data
->parser
, child_data
);
931 if (key_name
== null) {
932 Console
.Error
.WriteLine ("Attempting to add item to a resource dictionary without an x:Key or x:Name");
933 throw new XamlParseException (-1, -1, "You must specify an x:Key or x:Name for elements in a ResourceDictionary");
937 the_dict
.Add (key_name
, child
);
938 if (child
is DependencyObject
&& parent
is DependencyObject
&& !(the_dict
is DependencyObject
)) {
939 NativeMethods
.dependency_object_set_parent_safe (((DependencyObject
) child
).native
, ((DependencyObject
) parent
).native
);
943 } catch (Exception e
) {
944 // Fall through to string
945 Console
.Error
.WriteLine (e
);
950 IList the_list
= parent
as IList
;
951 if (the_list
!= null) {
954 the_list
.Add (child
);
956 if (child
is DependencyObject
&& parent
is DependencyObject
&& !(the_list
is DependencyObject
)) {
957 NativeMethods
.dependency_object_set_parent_safe (((DependencyObject
)child
).native
, ((DependencyObject
)parent
).native
);
967 Type parent_type
= parent
.GetType ();
968 PropertyInfo pi
= GetContentProperty (parent_type
);
971 Console
.Error
.WriteLine ("Unable to find content property on type {0}", parent_type
);
976 // Is the content property a collection
978 if (typeof (IList
).IsAssignableFrom (pi
.PropertyType
) && !(child
is IList
)) {
979 the_list
= (IList
) pi
.GetValue (parent
, null);
981 if (the_list
== null) {
982 the_list
= (IList
) Activator
.CreateInstance (pi
.PropertyType
);
983 if (the_list
== null) {
984 Console
.Error
.WriteLine ("Unable to create instance of list: " + pi
.PropertyType
);
987 pi
.SetValue (parent
, the_list
, null);
991 the_list
.Add (child
);
993 if (child
is DependencyObject
&& parent
is DependencyObject
&& !(the_list
is DependencyObject
)) {
994 NativeMethods
.dependency_object_set_parent_safe (((DependencyObject
)child
).native
, ((DependencyObject
)parent
).native
);
1006 return SetPropertyFromValue (data
, parent
, parent_data
, parent_parent_ptr
, pi
, child_ptr
, child_data
, out error
);
1008 throw new XamlParseException (2010, String
.Format ("{0} does not support {1} as content.", parent
, child
));
1012 private unsafe Type
LookupType (Value
* top_level
, string assembly_name
, string full_name
)
1016 if (assembly_name
!= null) {
1018 // if we're given an explicit assembly
1019 // name, try and load it, then get the
1020 // type from just that assembly
1022 Assembly assembly
= null;
1023 if (LoadAssembly (assembly_name
, out assembly
) == AssemblyLoadResult
.Success
) {
1024 res
= assembly
.GetType (full_name
);
1029 Console
.Error
.WriteLine ("unable to load assembly for target type.");
1034 // if we're not given an explicit
1035 // assembly name, loop over all
1036 // assemblies specified in
1037 // Deployment.Parts looking for the
1039 foreach (Assembly a
in Deployment
.Current
.Assemblies
) {
1040 res
= a
.GetType (full_name
);
1045 Assembly assembly
= typeof (DependencyObject
).Assembly
;
1046 res
= assembly
.GetType (full_name
);
1047 if (res
!= null && res
.IsPublic
)
1052 return Application
.GetComponentTypeFromName (full_name
);
1055 private unsafe void SetCLRPropertyFromString (XamlCallbackData
*data
, IntPtr target_data
, object target
, PropertyInfo pi
, string value, out string error
, out IntPtr unmanaged_value
)
1057 unmanaged_value
= IntPtr
.Zero
;
1060 object new_value
= null;
1064 if (IsExplicitNull (value)) {
1065 Type t
= pi
.PropertyType
;
1066 if (t
.IsValueType
&& !(t
.IsGenericType
&& t
.GetGenericTypeDefinition () == typeof (Nullable
<>))) {
1067 error
= "Unable to set non nullable type to null.";
1072 new_value
= MoonlightTypeConverter
.ConvertObject (pi
, value, target
.GetType ());
1079 SetValue (data
, target_data
, pi
, target
, new_value
);
1081 } catch (Exception ex
) {
1088 // lastly, attempt to create an unmanaged Value* object, if one is created, the managed
1089 // parser will create a managed wrapper for the object and call SetPropertyFromValue with
1090 // the managed object
1092 bool result
= NativeMethods
.value_from_str_with_typename (TypeToMoonType (pi
.PropertyType
), pi
.Name
, value, out unmanaged_value
);
1094 error
= string.Format ("unable to convert to type {0} from a string", pi
.PropertyType
);
1098 private string TypeToMoonType (Type t
)
1100 if (t
== typeof (double))
1102 if (t
== typeof (bool))
1108 // TODO: Is it legal to jam the whole metadata right in the string ie: TargetType="clr-namespace:Mono;MyType"
1110 private unsafe Type
TypeFromString (XamlCallbackData
*data
, string str
)
1112 string assembly_name
= null;
1113 string full_name
= str
;
1115 int ps
= str
.IndexOf (':');
1117 string xmlns
= NativeMethods
.xaml_uri_for_prefix (data
->parser
, str
.Substring (0, ps
));
1118 string name
= str
.Substring (ps
+ 1, str
.Length
- ps
-1);
1120 return TypeFromString (data
, xmlns
, name
);
1123 return LookupType (data
->top_level
, assembly_name
, full_name
);
1126 private unsafe Type
TypeFromString (XamlCallbackData
*data
, string xmlns
, string name
)
1128 string clr_namespace
= ClrNamespaceFromXmlns (xmlns
);
1129 string assembly_name
= AssemblyNameFromXmlns (xmlns
);
1131 string full_name
= string.IsNullOrEmpty (clr_namespace
) ? name
: clr_namespace
+ "." + name
;
1133 return LookupType (data
->top_level
, assembly_name
, full_name
);
1136 private unsafe DependencyProperty
DependencyPropertyFromString (XamlCallbackData
*data
, object otarget
, Value
* target_parent_ptr
, string str_value
)
1138 object o
= Value
.ToObject (null, target_parent_ptr
);
1139 Style parent
= o
as Style
;
1141 if (parent
== null) {
1142 Console
.Error
.WriteLine ("DependencyPropertyFromString Parent of target is not a Style. It's a {0}", o
);
1146 Type target_type
= parent
.TargetType
;
1147 if (target_type
== null) {
1148 Console
.Error
.WriteLine ("DependencyPropertyFromString TargetType is null.");
1153 // Check to see if we have an attached property
1155 int dot
= str_value
.IndexOf ('.');
1157 string type_name
= str_value
.Substring (0, dot
);
1158 str_value
= str_value
.Substring (++dot
, str_value
.Length
- dot
);
1160 target_type
= TypeFromString (data
, type_name
);
1163 Types
.Ensure (target_type
);
1165 ManagedType mt
= Deployment
.Current
.Types
.Find (target_type
);
1166 DependencyProperty dp
= DependencyProperty
.Lookup ((Kind
) mt
.native_handle
, str_value
);
1171 private unsafe bool SetPropertyFromValue (XamlCallbackData
*data
, object target
, IntPtr target_data
, Value
* target_parent_ptr
, PropertyInfo pi
, Value
* value_ptr
, IntPtr value_data
, out string error
)
1174 object obj_value
= Value
.ToObject (null, value_ptr
);
1176 if (pi
.GetCustomAttributes (typeof (SetPropertyDelayedAttribute
), true).Length
> 0) {
1177 if ((data
->flags
& XamlCallbackFlags
.SettingDelayedProperty
) == 0) {
1178 Value v
= *value_ptr
;
1179 NativeMethods
.xaml_delay_set_property (data
->parser
, target_data
, null, pi
.Name
, ref v
);
1184 if (obj_value
is Binding
&& target
is FrameworkElement
) {
1185 FrameworkElement fe
= (FrameworkElement
) target
;
1186 fe
.SetBinding (DependencyProperty
.Lookup (fe
.GetKind (), pi
.Name
), (Binding
) obj_value
);
1190 if (obj_value
is StaticResource
) {
1191 StaticResource sr
= (StaticResource
)obj_value
;
1192 obj_value
= "{StaticResource " + sr.ResourceKey + "}";
1195 if (typeof (IList
).IsAssignableFrom (pi
.PropertyType
) && !(obj_value
is IList
)) {
1196 // This case is handled in the AddChild code
1200 if (typeof (ResourceDictionary
).IsAssignableFrom (pi
.PropertyType
) && !(obj_value
is ResourceDictionary
)) {
1201 // This case is handled in the AddChild code
1205 string str_value
= obj_value
as string;
1206 if (str_value
!= null) {
1207 IntPtr unmanaged_value
;
1209 if (pi
.PropertyType
== typeof (Type
)) {
1210 Type t
= TypeFromString (data
, str_value
);
1212 SetValue (data
, target_data
, pi
, target
, t
);
1217 if (pi
.PropertyType
== typeof (DependencyProperty
)) {
1218 DependencyProperty dp
= DependencyPropertyFromString (data
, target
, target_parent_ptr
, str_value
);
1220 SetValue (data
, target_data
, pi
, target
, dp
);
1225 if (typeof (System
.Windows
.Data
.Binding
).IsAssignableFrom (pi
.PropertyType
) && MarkupExpressionParser
.IsBinding (str_value
)) {
1226 MarkupExpressionParser p
= new MarkupExpressionParser (null, pi
.Name
, data
->parser
, target_data
);
1228 string expression
= str_value
;
1229 obj_value
= p
.ParseExpression (ref expression
);
1231 if (!(obj_value
is Binding
))
1234 SetValue (data
, target_data
, pi
, target
, obj_value
);
1238 if (MarkupExpressionParser
.IsStaticResource (str_value
)) {
1239 // FIXME: The NUnit tests show we need to use the parent of the target to resolve
1240 // the StaticResource, but are there any cases where we should use the actual target?
1241 DependencyObject parent
= Value
.ToObject (null, target_parent_ptr
) as DependencyObject
;
1244 MarkupExpressionParser p
= new MarkupExpressionParser (parent
, "", data
->parser
, target_data
);
1245 obj_value
= p
.ParseExpression (ref str_value
);
1246 obj_value
= ConvertType (pi
, pi
.PropertyType
, obj_value
);
1248 SetValue (data
, target_data
, pi
, target
, obj_value
);
1252 SetCLRPropertyFromString (data
, target_data
, target
, pi
, str_value
, out error
, out unmanaged_value
);
1254 if (error
== null && unmanaged_value
!= IntPtr
.Zero
)
1255 obj_value
= Value
.ToObject (null, unmanaged_value
);
1257 return error
== null;
1259 obj_value
= Value
.ToObject (pi
.PropertyType
, value_ptr
);
1262 obj_value
= ConvertType (pi
, pi
.PropertyType
, obj_value
);
1263 SetValue (data
, target_data
, pi
, target
, obj_value
);
1268 private static unsafe void SetValue (XamlCallbackData
*data
, IntPtr target_data
, PropertyInfo pi
, object target
, object value)
1270 SetterBase sb
= target
as SetterBase
;
1273 sb
.IsSealed
= false;
1276 if (NativeMethods
.xaml_is_property_set (data
->parser
, target_data
, pi
.Name
))
1277 throw new XamlParseException (2033, String
.Format ("Cannot specify the value multiple times for property: {0}.", pi
.Name
));
1279 pi
.SetValue (target
, value, null);
1281 NativeMethods
.xaml_mark_property_as_set (data
->parser
, target_data
, pi
.Name
);
1289 private static object ConvertType (MemberInfo pi
, Type t
, object value)
1294 Type valueType
= value.GetType ();
1300 string str_value
= value as string;
1301 if (str_value
!= null)
1302 return Enum
.Parse (t
, str_value
, true);
1303 if (Enum
.IsDefined (t
, value))
1304 return Enum
.ToObject (t
, value);
1309 TypeConverter converter
= Helper
.GetConverterFor (pi
, t
);
1310 if (converter
== null) {
1312 converter
= new MoonlightTypeConverter (pi
== null ? null : pi
.Name
, t
);
1318 if (converter
!= null && converter
.CanConvertFrom (value.GetType ()))
1319 return converter
.ConvertFrom (value);
1322 if (!valueType
.IsSubclassOf (t
))
1323 value = Convert
.ChangeType (value, t
, System
.Globalization
.CultureInfo
.CurrentCulture
);
1327 // This will just let things fail
1331 private static string ClrNamespaceFromXmlns (string xmlns
)
1333 if (String
.IsNullOrEmpty (xmlns
))
1336 int start
= xmlns
.IndexOf ("clr-namespace:");
1340 start
+= "clr-namespace:".Length
;
1342 int end
= xmlns
.IndexOf (';', start
);
1346 return xmlns
.Substring (start
, end
- start
);
1349 private static string AssemblyNameFromXmlns (string xmlns
)
1351 if (String
.IsNullOrEmpty (xmlns
))
1354 int start
= xmlns
.IndexOf ("assembly=");
1358 start
+= "assembly=".Length
;
1359 int end
= xmlns
.IndexOf (';', start
);
1362 return xmlns
.Substring (start
, end
- start
);
1365 private static bool ValidateXmlns (string xmlns
)
1368 if (Uri
.TryCreate (xmlns
, UriKind
.Absolute
, out dummy
))
1371 int start
= xmlns
.IndexOf ("clr-namespace");
1372 int end
= start
+ "clr-namespace".Length
;
1373 if (end
>= xmlns
.Length
|| xmlns
[end
] != ':')
1376 start
= xmlns
.IndexOf ("assembly");
1378 end
= start
+ "assembly".Length
;
1379 if (end
>= xmlns
.Length
|| xmlns
[end
] != '=')
1386 private unsafe MethodInfo
GetSetMethodForAttachedProperty (Value
*top_level
, string xmlns
, string type_name
, string full_type_name
, string prop_name
)
1388 string assembly_name
= AssemblyNameFromXmlns (xmlns
);
1389 string ns
= ClrNamespaceFromXmlns (xmlns
);
1391 if (assembly_name
== null && !TryGetDefaultAssemblyName (top_level
, out assembly_name
)) {
1392 Console
.Error
.WriteLine ("Unable to find an assembly to load type from.");
1397 if (LoadAssembly (assembly_name
, out clientlib
) != AssemblyLoadResult
.Success
) {
1398 Console
.Error
.WriteLine ("couldn't load assembly: {0} namespace: {1}", assembly_name
, ns
);
1402 Type attach_type
= clientlib
.GetType (full_type_name
, false);
1403 if (attach_type
== null) {
1404 attach_type
= Application
.GetComponentTypeFromName (type_name
);
1405 if (attach_type
== null) {
1406 Console
.Error
.WriteLine ("attach type is null type name: {0} full type name: {1}", type_name
, full_type_name
);
1411 MethodInfo set_method
= attach_type
.GetMethod (String
.Concat ("Set", prop_name
), BindingFlags
.Static
| BindingFlags
.Public
| BindingFlags
.NonPublic
);
1415 private static unsafe object GetObjectValue (object target
, IntPtr target_data
, string prop_name
, IntPtr parser
, Value
* value_ptr
, out string error
)
1419 IntPtr unmanaged_value
= IntPtr
.Zero
;
1420 object o_value
= Value
.ToObject (null, value_ptr
);
1421 if (error
== null && unmanaged_value
!= IntPtr
.Zero
)
1422 o_value
= Value
.ToObject (null, unmanaged_value
);
1424 if (o_value
is String
&& MarkupExpressionParser
.IsStaticResource ((string) o_value
)) {
1425 MarkupExpressionParser mp
= new MarkupExpressionParser ((DependencyObject
) target
, prop_name
, parser
, target_data
);
1426 string str_value
= o_value
as String
;
1427 o_value
= mp
.ParseExpression (ref str_value
);
1433 private static bool IsExplicitNull (string value)
1435 return Regex
.IsMatch (value, "^{\\s*x:Null\\s*}");
1438 private PropertyInfo
GetContentProperty (Type t
)
1441 string content_property
= null;
1443 while (walk
!= null) {
1444 content_property
= GetContentPropertyNameForType (walk
);
1445 if (content_property
!= null)
1447 walk
= walk
.BaseType
;
1450 if (walk
== null || content_property
== null)
1453 PropertyInfo pi
= walk
.GetProperty (content_property
, BindingFlags
.Instance
| BindingFlags
.NonPublic
| BindingFlags
.Public
| BindingFlags
.FlattenHierarchy
);
1457 private string GetContentPropertyNameForType (Type t
)
1459 object [] o
= t
.GetCustomAttributes (typeof (ContentPropertyAttribute
), false);
1464 ContentPropertyAttribute cpa
= (ContentPropertyAttribute
) o
[0];
1468 private string GetContentPropertyName (Type t
)
1470 object [] o
= t
.GetCustomAttributes (typeof (ContentPropertyAttribute
), true);
1473 ContentPropertyAttribute cpa
= (ContentPropertyAttribute
) o
[0];
1480 /// Callbacks invoked by the xaml.cpp C++ parser
1484 #region Callbacks from xaml.cpp
1486 // Proxy so that we return IntPtr.Zero in case of any failures, instead of
1487 // genereting an exception and unwinding the stack.
1489 private unsafe bool cb_lookup_object (XamlCallbackData
*data
, Value
* parent
, string xmlns
, string name
, bool create
, bool is_property
, out Value
value, ref MoonError error
)
1492 return LookupObject (data
->top_level
, parent
, xmlns
, name
, create
, is_property
, out value);
1493 } catch (Exception ex
) {
1494 Console
.Error
.WriteLine ("ManagedXamlLoader::LookupObject ({0}, {1}, {2}, {3}) failed: {3} ({4}).", (IntPtr
) data
->top_level
, xmlns
, create
, name
, ex
.Message
, ex
.GetType ().FullName
);
1495 Console
.WriteLine (ex
);
1496 value = Value
.Empty
;
1497 error
= new MoonError (ex
);
1502 private void cb_create_gchandle ()
1504 if (!handle
.IsAllocated
)
1505 handle
= GCHandle
.Alloc (this);
1509 // Proxy so that we return IntPtr.Zero in case of any failures, instead of
1510 // generating an exception and unwinding the stack.
1512 private unsafe bool cb_set_property (XamlCallbackData
*data
, string xmlns
, Value
* target
, IntPtr target_data
, Value
* target_parent
, string prop_xmlns
, string name
, Value
* value_ptr
, IntPtr value_data
, ref MoonError error
)
1515 return SetProperty (data
, xmlns
, target
, target_data
, target_parent
, prop_xmlns
, name
, value_ptr
, value_data
);
1516 } catch (Exception ex
) {
1518 Console
.Error
.WriteLine ("ManagedXamlLoader::SetProperty ({0}, {1}, {2}, {3}, {4}) threw an exception: {5}.", (IntPtr
) data
->top_level
, xmlns
, (IntPtr
)target
, name
, (IntPtr
)value_ptr
, ex
.Message
);
1519 Console
.Error
.WriteLine (ex
);
1520 error
= new MoonError (ex
);
1529 private unsafe bool cb_import_xaml_xmlns (XamlCallbackData
*data
, string xmlns
, ref MoonError error
)
1532 if (!ValidateXmlns (xmlns
))
1534 Application
.ImportXamlNamespace (xmlns
);
1536 } catch (Exception ex
) {
1537 Console
.WriteLine ("Application::ImportXamlNamespace ({0}) threw an exception:\n{1}", xmlns
, ex
);
1538 error
= new MoonError (ex
);
1544 private unsafe string cb_get_content_property_name (XamlCallbackData
*data
, Value
* object_ptr
, ref MoonError error
)
1546 object obj
= Value
.ToObject (null, object_ptr
);
1551 Type t
= obj
.GetType ();
1552 return GetContentPropertyName (t
);
1556 private unsafe bool cb_add_child (XamlCallbackData
*data
, Value
* parent_parent
, bool parent_is_property
, string parent_xmlns
, Value
*parent
, IntPtr parent_data
, Value
* child
, IntPtr child_data
, ref MoonError error
)
1559 return AddChild (data
, parent_parent
, parent_is_property
, parent_xmlns
, parent
, parent_data
, child
, child_data
);
1560 } catch (Exception ex
) {
1561 Console
.Error
.WriteLine (ex
);
1562 error
= new MoonError (ex
);