in class/System.Windows/Mono:
[moon.git] / class / System.Windows / Mono / ManagedXamlLoader.cs
blob0647ad920accc7a841afe10f4c0686d02bd40381
1 //
2 // ManagedXamlLoader.cs
3 //
4 // Contact:
5 // Moonlight List (moonlight-list@lists.ximian.com)
6 //
7 // Copyright 2007 Novell, Inc.
8 //
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
29 using System;
30 using System.Collections;
31 using System.Diagnostics;
32 using System.Reflection;
33 using System.Collections.Generic;
34 using System.IO;
35 using System.Windows;
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;
42 using Mono;
44 namespace Mono.Xaml
46 internal class ManagedXamlLoader : XamlLoader {
48 Assembly assembly;
49 XamlLoaderCallbacks callbacks;
50 GCHandle handle;
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
67 // unmanaged code.
69 unsafe {
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;
89 //
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)
99 if (xaml == null)
100 throw new ArgumentNullException ("xaml");
102 IntPtr top;
103 object result;
104 Kind kind;
106 DependencyObject.Initialize ();
108 top = CreateFromString (xaml, createNamescope, validateTemplates, out kind);
110 if (top == IntPtr.Zero)
111 return null;
113 result = Value.ToObject (null, top);
114 DependencyObject dob = result as DependencyObject;
115 if (dob != null) {
116 NativeMethods.event_object_unref (dob.native);
119 return result;
123 // Creates a managed dependency object from the xaml in the file
125 public override object CreateObjectFromFile (string file, bool createNamescope)
127 if (file == null)
128 throw new ArgumentNullException ("file");
130 IntPtr top;
131 object result;
132 Kind kind;
134 DependencyObject.Initialize ();
136 top = CreateFromFile (file, createNamescope, out kind);
138 if (top == IntPtr.Zero)
139 return null;
141 result = Value.ToObject (null, top);
142 DependencyObject dob = result as DependencyObject;
143 if (dob != null) {
144 NativeMethods.event_object_unref (dob.native);
147 return result;
151 // Tries to load the assembly.
153 public AssemblyLoadResult LoadAssembly (string asm_name, out Assembly clientlib)
155 clientlib = null;
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;
165 return true;
168 object obj = Value.ToObject (null, top_level);
170 if (obj == null) {
171 assembly_name = null;
172 return false;
175 assembly_name = obj.GetType ().Assembly.GetName ().Name;
176 return true;
179 private unsafe bool LookupObject (Value *top_level, Value *parent, string xmlns, string name, bool create, bool is_property, out Value value)
181 if (name == null)
182 throw new ArgumentNullException ("type_name");
185 if (is_property) {
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);
199 if (type == null) {
200 Console.Error.WriteLine ("ManagedXamlLoader::LookupObject: GetType ({0}) failed using assembly: {1} ({2}, {3}).", name, assembly_name, xmlns, full_name);
201 value = Value.Empty;
202 return false;
205 if (create) {
207 if (!type.IsPublic) {
208 value = Value.Empty;
209 throw new XamlParseException ("Attempting to create a private type");
212 object res = null;
213 try {
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);
218 value = Value.Empty;
219 return false;
222 if (res == null) {
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);
225 value = Value.Empty;
226 return false;
228 value = Value.FromObject (res, false);
229 } else {
230 value = Value.Empty;
231 value.k = Deployment.Current.Types.Find (type).native_handle;
234 return true;
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) {
243 value = Value.Empty;
244 return false;
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) {
254 is_attached = false;
255 break;
257 t = t.BaseType;
260 if (is_attached) {
261 MethodInfo set_method = GetSetMethodForAttachedProperty (top_level, xmlns, type_name, prop_name);
263 ParameterInfo [] set_params = set_method.GetParameters ();
264 if (set_params == null || set_params.Length < 2) {
265 value = Value.Empty;
266 Console.Error.WriteLine ("set method signature is incorrect.");
267 return false;
270 ManagedType mt = Deployment.Current.Types.Find (set_params [1].ParameterType);
271 value = Value.Empty;
272 value.IsNull = true;
273 value.k = mt.native_handle;
274 return true;
275 } else {
277 pi = parent.GetType ().GetProperty (name.Substring (dot + 1), BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy);
279 if (pi == null) {
280 value = Value.Empty;
281 return false;
284 ManagedType mt = Deployment.Current.Types.Find (pi.PropertyType);
285 value = Value.Empty;
286 value.k = mt.native_handle;
287 value.IsNull = true;
289 return true;
293 private unsafe bool LookupComponentFromName (Value* top_level, string name, bool create, out Value value)
295 if (!create) {
296 Type type = Application.GetComponentTypeFromName (name);
297 if (type == null) {
298 value = Value.Empty;
299 return false;
301 value = Value.Empty;
302 value.k = Deployment.Current.Types.Find (type).native_handle;
303 return true;
306 object obj = Application.CreateComponentFromName (name);
307 if (obj == null) {
308 value = Value.Empty;
309 return false;
312 value = Value.FromObject (obj, false);
313 return true;
316 private static bool IsAttachedProperty (string name)
318 return name.IndexOf ('.') > 0;
321 private unsafe DependencyProperty LookupDependencyPropertyForBinding (XamlCallbackData *data, FrameworkElement fwe, string type_name, string propertyName)
323 // map the property name + type_name to an actual DependencyProperty
324 Kind kind;
325 Type type = string.IsNullOrEmpty (type_name) ? null : TypeFromString (data, type_name);
326 if (type != null) {
327 Types.Ensure (type);
328 kind = Deployment.Current.Types.TypeToNativeKind (type);
329 } else {
330 kind = fwe.GetKind ();
333 if (kind == Kind.INVALID)
334 return null;
336 try {
337 return DependencyProperty.Lookup (kind, propertyName);
339 catch {
340 return null;
345 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)
347 FrameworkElement dob = target as FrameworkElement;
348 object obj_value = Value.ToObject (null, value_ptr);
349 string str_value = obj_value as string;
351 if (str_value == null)
352 return false;
354 if (!str_value.StartsWith ("{"))
355 return false;
357 MarkupExpressionParser p = new MarkupExpressionParser (target, name, data->parser, target_data);
358 string expression = str_value;
359 object o = p.ParseExpression (ref expression);
361 if (o == null)
362 return false;
365 if (o is Binding) {
366 Binding binding = o as Binding;
367 DependencyProperty prop = null;
369 if (dob != null)
370 prop = LookupDependencyPropertyForBinding (data, dob, type_name, name);
372 if (prop == null)
373 return false;
375 dob.SetBinding (prop, binding);
376 return true;
378 else if (o is TemplateBindingExpression) {
379 // Applying a {TemplateBinding} to a DO which is not a FrameworkElement should silently discard
380 // the binding.
381 if (dob == null)
382 return true;
384 TemplateBindingExpression tb = o as TemplateBindingExpression;
386 IntPtr context = NativeMethods.xaml_loader_get_context (data->loader);
387 IntPtr source_ptr = NativeMethods.xaml_context_get_template_binding_source (context);
389 DependencyObject templateSourceObject = NativeDependencyObjectHelper.FromIntPtr (source_ptr) as DependencyObject;
391 if (templateSourceObject == null)
392 return false;
394 DependencyProperty sourceProperty = DependencyProperty.Lookup (templateSourceObject.GetKind(),
395 tb.SourcePropertyName);
396 if (sourceProperty == null)
397 return false;
399 DependencyProperty prop = null;
401 if (dob != null)
402 prop = LookupDependencyPropertyForBinding (data, dob, type_name, name);
404 if (prop == null)
405 return false;
407 tb.TargetProperty = prop;
408 tb.Source = templateSourceObject as Control;
409 tb.SourceProperty = sourceProperty;
411 dob.SetTemplateBinding (prop, tb);
413 return true;
415 else {
416 // static resources fall into this
418 if (dob != null) {
419 DependencyProperty prop = LookupDependencyPropertyForBinding (data, dob, type_name, name);
420 if (prop == null)
421 return false;
423 o = ConvertType (null, prop.PropertyType, o);
424 dob.SetValue (prop, o);
425 } else {
426 if (IsAttachedProperty (full_name))
427 return TrySetAttachedProperty (data, xmlns, target, target_data, prop_xmlns, full_name, o);
429 PropertyInfo pi = target.GetType ().GetProperty (name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy);
431 o = ConvertType (null, pi.PropertyType, o);
432 SetValue (data, target_data, pi, target, o);
433 return true;
437 return true;
440 private string GetNameForAttachedProperty (string xmlns, string prop_xmlns, string name, out string type_name)
442 int dot = name.IndexOf ('.');
444 if (dot >= 0) {
445 type_name = name.Substring (0, dot);
446 if (prop_xmlns != null || xmlns != null) {
447 string ns = ClrNamespaceFromXmlns (prop_xmlns == null ? xmlns : prop_xmlns);
448 if (ns != null)
449 type_name = String.Concat (ns, ".", type_name);
451 name = name.Substring (++dot, name.Length - dot);
452 } else {
453 type_name = null;
454 return null;
457 return name;
460 private unsafe bool TrySetAttachedProperty (XamlCallbackData *data, string xmlns, object target, IntPtr target_data, string prop_xmlns, string name, Value* value_ptr)
462 string full_name = name;
463 string type_name = null;
465 name = GetNameForAttachedProperty (xmlns, prop_xmlns, name, out type_name);
467 if (name == null)
468 return false;
470 string error = null;
471 object o_value = GetObjectValue (target, target_data, name, data->parser, value_ptr, out error);
473 return TrySetAttachedProperty (data, xmlns, target, target_data, prop_xmlns, full_name, o_value);
476 private unsafe bool TrySetAttachedProperty (XamlCallbackData *data, string xmlns, object target, IntPtr target_data, string prop_xmlns, string name, object o_value)
478 string type_name = null;
480 name = GetNameForAttachedProperty (xmlns, prop_xmlns, name, out type_name);
482 if (name == null)
483 return false;
485 MethodInfo set_method = GetSetMethodForAttachedProperty (data->top_level, prop_xmlns, type_name, name);
486 if (set_method == null) {
487 Console.Error.WriteLine ("set method is null: {0} {1}", String.Concat ("Set", name), prop_xmlns);
488 return false;
491 ParameterInfo [] set_params = set_method.GetParameters ();
492 if (set_params == null || set_params.Length < 2) {
493 Console.Error.WriteLine ("set method signature is inccorrect.");
494 return false;
497 MethodInfo get_method = set_method.DeclaringType.GetMethod (String.Concat ("Get", name), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
500 // The Setter might actually want a collection, in this case we grab the old collection with the getter
501 // and then add the new object to the collection
503 // TODO: Check if the setter method still gets called on Silverlight
504 if (typeof (IList).IsAssignableFrom (set_params [1].ParameterType) && !(o_value is IList)) {
506 if (get_method != null || get_method.GetParameters () == null || get_method.GetParameters ().Length != 1) {
507 IList the_list = (IList) get_method.Invoke (null, new object [] { target });
509 if (the_list == null) {
510 the_list = (IList) Activator.CreateInstance (set_params [1].ParameterType);
511 if (the_list == null)
512 return false;
513 set_method.Invoke (null, new object [] {target, the_list});
516 try {
517 the_list.Add (o_value);
519 if (o_value is DependencyObject && target is DependencyObject && !(the_list is DependencyObject)) {
520 NativeMethods.dependency_object_set_parent (((DependencyObject)o_value).native, ((DependencyObject)target).native);
523 return true;
525 catch {
526 // don't return here, fall through to the ConvertType case below.
528 } else {
529 // I guess we need to wrap the current value in a collection, or does this error out?
530 Console.WriteLine ("ow god my eye!");
531 return false;
535 o_value = ConvertType (get_method, set_params [1].ParameterType, o_value);
536 set_method.Invoke (null, new object [] {target, o_value});
537 return true;
540 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)
542 PropertyInfo pi = target.GetType ().GetProperty (name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy);
544 if (pi == null) {
545 error = "Property does not exist.";
546 return false;
549 if (!SetPropertyFromValue (data, target, target_data, target_parent_ptr, pi, value_ptr, value_data, out error))
550 return false;
552 error = null;
553 return true;
556 private unsafe bool TrySetEventReflection (XamlCallbackData *data, string xmlns, object publisher, string type_name, string name, Value* value_ptr, out string error)
558 object subscriber = null;
559 EventInfo ie = publisher.GetType ().GetEvent (name);
560 string handler_name = Value.ToObject (null, value_ptr) as string;
562 try {
563 subscriber = Value.ToObject (null, data->top_level);
564 } catch {
568 //Console.WriteLine ("TrySetEventReflection ({0}, {1}, {2}, {3}, {4}, {5}) handler_name: {6}", data->top_level, xmlns, publisher, type_name, name, value_ptr, handler_name);
570 if (ie == null) {
571 error = "Event does not exist.";
572 return false;
576 if (handler_name == null) {
577 error = "No method name supplied for event handler.";
578 return false;
581 MethodInfo invoker_info = ie.EventHandlerType.GetMethod ("Invoke");
582 ParameterInfo [] event_params = invoker_info.GetParameters ();
584 Delegate d = null;
585 Type stype = subscriber.GetType ();
586 MethodInfo [] methods = stype.GetMethods (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance);
587 MethodInfo candidate = null;
588 bool name_match = false;
590 for (int i = 0; i < methods.Length; i++) {
591 MethodInfo m = methods [i];
592 ParameterInfo [] parameters;
594 if (m.Name != handler_name)
595 continue;
597 if (name_match) {
598 error = "Multiple candidates with the same name found for event handler.";
599 // Console.WriteLine (error);
600 return false;
603 name_match = true;
605 if (m.ReturnType != typeof (void))
606 continue;
608 parameters = m.GetParameters ();
610 if (parameters.Length != event_params.Length)
611 continue;
613 bool match = true;
614 for (int p = 0; p < parameters.Length; p++) {
615 if (!event_params [p].ParameterType.IsSubclassOf (parameters [p].ParameterType) && parameters [p].ParameterType != event_params [p].ParameterType) {
616 Console.WriteLine ("mismatch: {0} and {1}", parameters [p].ParameterType, event_params [p].ParameterType);
617 match = false;
618 break;
622 if (!match)
623 continue;
625 if (candidate != null) {
626 error = "Multiple candidates for event handler found.";
627 // Console.WriteLine (error);
628 return false;
631 candidate = m;
634 if (candidate == null) {
635 error = "Event handler not found.";
636 // Console.WriteLine (error);
637 return false;
640 d = Delegate.CreateDelegate (ie.EventHandlerType, subscriber, candidate, false);
642 if (d == null) {
643 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);
644 error = "Can not create even delegate.";
645 return false;
648 // 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);
650 error = null;
651 ie.AddEventHandler (publisher, d);
652 return true;
655 private unsafe bool TrySetEnumContentProperty (XamlCallbackData *data, string xmlns, object target, Value* target_ptr, IntPtr target_data, Value* value_ptr, IntPtr value_data)
657 object obj_value = Value.ToObject (null, value_ptr);
658 string str_value = obj_value as string;
660 if (str_value == null)
661 return false;
663 string assembly_name = AssemblyNameFromXmlns (xmlns);
664 string clr_namespace = ClrNamespaceFromXmlns (xmlns);
665 string type_name = NativeMethods.xaml_get_element_name (data->parser, target_data);
666 string full_name = String.IsNullOrEmpty (clr_namespace) ? type_name : clr_namespace + "." + type_name;
668 Type type = LookupType (data->top_level, assembly_name, full_name);
670 if (type == null || !type.IsEnum)
671 return false;
673 object e = Enum.Parse (type, str_value, true);
675 NativeMethods.value_free_value2 ((IntPtr)target_ptr);
677 unsafe {
678 Value *val = (Value *) target_ptr;
680 GCHandle handle = GCHandle.Alloc (e);
681 val->k = Kind.MANAGED;
682 val->u.p = GCHandle.ToIntPtr (handle);
685 return true;
688 private unsafe bool TrySetCollectionContentProperty (string xmlns, object target, Value* target_ptr, IntPtr target_data, Value* value_ptr, IntPtr value_data)
690 IList list = target as IList;
692 if (list == null)
693 return false;
695 object value = Value.ToObject (null, value_ptr);
697 list.Add (value);
698 return true;
701 private unsafe bool TrySetObjectTextProperty (XamlCallbackData *data, string xmlns, object target, Value* target_ptr, IntPtr target_data, Value* value_ptr, IntPtr value_data)
703 object obj_value = Value.ToObject (null, value_ptr);
704 string str_value = obj_value as string;
706 if (str_value == null)
707 return false;
709 string assembly_name = AssemblyNameFromXmlns (xmlns);
710 string clr_namespace = ClrNamespaceFromXmlns (xmlns);
711 string type_name = NativeMethods.xaml_get_element_name (data->parser, target_data);
712 string full_name = String.IsNullOrEmpty (clr_namespace) ? type_name : clr_namespace + "." + type_name;
714 Type type = LookupType (data->top_level, assembly_name, full_name);
716 if (type == null || type.IsSubclassOf (typeof (DependencyObject)))
717 return false;
719 // For now just trim the string right here, in the future this should probably be done in the xaml parser
720 object e = ConvertType (null, type, str_value.Trim ());
722 NativeMethods.value_free_value2 ((IntPtr)target_ptr);
724 unsafe {
725 Value *val = (Value *) target_ptr;
727 GCHandle handle = GCHandle.Alloc (e);
728 val->k = Kind.MANAGED;
729 val->u.p = GCHandle.ToIntPtr (handle);
732 return true;
735 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)
737 string error;
738 object target = Value.ToObject (null, target_ptr);
740 if (target == null) {
741 Console.Error.WriteLine ("target is null: {0} {1} {2}", (IntPtr)target_ptr, name, xmlns);
742 return false;
745 if (name == null) {
746 if (TrySetEnumContentProperty (data, xmlns, target, target_ptr, target_data, value_ptr, value_data))
747 return true;
748 if (TrySetCollectionContentProperty (xmlns, target, target_ptr, target_data, value_ptr, value_data))
749 return true;
750 if (TrySetObjectTextProperty (data, xmlns, target, target_ptr, target_data, value_ptr, value_data))
751 return true;
752 Console.Error.WriteLine ("no property name supplied");
753 return false;
756 string full_name = name;
757 int dot = name.IndexOf ('.');
758 string type_name = null;
760 if (dot >= 0) {
761 type_name = name.Substring (0, dot);
762 if (xmlns != null) {
763 string ns = ClrNamespaceFromXmlns (xmlns);
764 if (ns != null)
765 type_name = String.Concat (ns, ".", type_name);
767 name = name.Substring (++dot, name.Length - dot);
770 if (TrySetExpression (data, xmlns, target, target_data, target_parent_ptr, type_name, prop_xmlns, name, full_name, value_ptr, value_data))
771 return true;
773 if (TrySetPropertyReflection (data, xmlns, target, target_data, target_parent_ptr, type_name, name, value_ptr, value_data, out error))
774 return true;
776 if (TrySetEventReflection (data, xmlns, target, type_name, name, value_ptr, out error))
777 return true;
779 if (TrySetAttachedProperty (data, xmlns, target, target_data, prop_xmlns, full_name, value_ptr))
780 return true;
782 return false;
785 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)
787 object parent_parent = Value.ToObject (null, parent_parent_ptr);
788 object parent = Value.ToObject (null, parent_ptr);
789 object child = Value.ToObject (null, child_ptr);
791 if (parent_is_property)
792 return AddChildToProperty (data, parent_parent, parent_xmlns, parent, child, child_data);
794 return AddChildToItem (data, parent_parent_ptr, parent, parent_data, child_ptr, child, child_data);
797 private unsafe bool AddChildToProperty (XamlCallbackData *data, object parent_parent, string parent_xmlns, object parent, object child, IntPtr child_data)
799 string full_prop_name = parent as string;
801 if (full_prop_name == null) {
802 Console.Error.WriteLine ("Attempting to add child to non string parent {0} as a property.", parent);
803 return false;
807 int dot = full_prop_name.IndexOf ('.');
808 if (dot < 1)
809 return false;
810 string type_name = full_prop_name.Substring (0, dot);
811 string prop_name = full_prop_name.Substring (++dot, full_prop_name.Length - dot);
813 Type target_type = TypeFromString (data, parent_xmlns, type_name);
815 if (target_type == null) {
816 Console.Error.WriteLine ("Type '{0}' with xmlns '{1}' could not be found", type_name, parent_xmlns);
817 return false;
820 if (!target_type.IsAssignableFrom (parent_parent.GetType ())) {
821 // This would happen with an attached property, we don't need to do anything here....do we?
822 return false;
825 PropertyInfo pi = parent_parent.GetType ().GetProperty (prop_name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy);
827 if (pi == null) {
828 Console.Error.WriteLine ("Property does not exist. {0}", prop_name);
829 return false;
832 if (typeof (ResourceDictionary).IsAssignableFrom (pi.PropertyType) && !(child is ResourceDictionary)) {
833 ResourceDictionary the_dict = (ResourceDictionary) pi.GetValue (parent_parent, null);
834 string key_name = NativeMethods.xaml_get_element_key (data->parser, child_data);
836 if (key_name == null) {
837 throw new XamlParseException (2034, "Elements in a ResourceDictionary must have x:Key or x:Name attribute.");
840 if (the_dict == null) {
841 the_dict = (ResourceDictionary) Activator.CreateInstance (pi.PropertyType);
842 if (the_dict == null) {
843 Console.Error.WriteLine ("Unable to create instance of dictionary: " + pi.PropertyType);
844 return false;
846 pi.SetValue (parent_parent, the_dict, null);
849 try {
850 the_dict.Add (key_name, child);
851 if (child is DependencyObject && parent_parent is DependencyObject && !(the_dict is DependencyObject)) {
852 NativeMethods.dependency_object_set_parent (((DependencyObject) child).native, ((DependencyObject) parent_parent).native);
855 return true;
856 } catch (ArgumentException) {
857 throw new XamlParseException (2273, "Elements in the same ResourceDictionary cannot have the same x:Key");
861 if (typeof (IList).IsAssignableFrom (pi.PropertyType) && !(child is IList)) {
862 IList the_list = (IList) pi.GetValue (parent_parent, null);
864 if (the_list == null) {
865 the_list = (IList) Activator.CreateInstance (pi.PropertyType);
866 if (the_list == null) {
867 Console.Error.WriteLine ("Unable to create instance of list: " + pi.PropertyType);
868 return false;
870 pi.SetValue (parent_parent, the_list, null);
873 try {
874 the_list.Add (child);
876 if (child is DependencyObject && parent_parent is DependencyObject && !(the_list is DependencyObject)) {
877 NativeMethods.dependency_object_set_parent (((DependencyObject)child).native, ((DependencyObject)parent_parent).native);
880 return true;
882 catch (Exception e) {
883 Console.WriteLine (e);
884 return false;
888 return true;
891 private unsafe bool AddChildToItem (XamlCallbackData *data, Value *parent_parent_ptr, object parent, IntPtr parent_data, Value *child_ptr, object child, IntPtr child_data)
893 ResourceDictionary the_dict = parent as ResourceDictionary;
894 if (the_dict != null) {
895 string key_name = NativeMethods.xaml_get_element_key (data->parser, child_data);
897 if (key_name == null) {
898 Console.Error.WriteLine ("Attempting to add item to a resource dictionary without an x:Key or x:Name");
899 throw new XamlParseException (-1, -1, "You must specify an x:Key or x:Name for elements in a ResourceDictionary");
902 try {
903 the_dict.Add (key_name, child);
904 if (child is DependencyObject && parent is DependencyObject && !(the_dict is DependencyObject)) {
905 NativeMethods.dependency_object_set_parent (((DependencyObject) child).native, ((DependencyObject) parent).native);
908 return true;
909 } catch (Exception e) {
910 // Fall through to string
911 Console.Error.WriteLine (e);
912 return false;
916 IList the_list = parent as IList;
917 if (the_list != null) {
919 try {
920 the_list.Add (child);
922 if (child is DependencyObject && parent is DependencyObject && !(the_list is DependencyObject)) {
923 NativeMethods.dependency_object_set_parent (((DependencyObject)child).native, ((DependencyObject)parent).native);
926 return true;
928 catch {
929 return false;
933 Type parent_type = parent.GetType ();
934 PropertyInfo pi = GetContentProperty (parent_type);
936 if (pi == null) {
937 Console.Error.WriteLine ("Unable to find content property on type {0}", parent_type);
938 return false;
942 // Is the content property a collection
944 if (typeof (IList).IsAssignableFrom (pi.PropertyType) && !(child is IList)) {
945 the_list = (IList) pi.GetValue (parent, null);
947 if (the_list == null) {
948 the_list = (IList) Activator.CreateInstance (pi.PropertyType);
949 if (the_list == null) {
950 Console.Error.WriteLine ("Unable to create instance of list: " + pi.PropertyType);
951 return false;
953 pi.SetValue (parent, the_list, null);
956 try {
957 the_list.Add (child);
959 if (child is DependencyObject && parent is DependencyObject && !(the_list is DependencyObject)) {
960 NativeMethods.dependency_object_set_parent (((DependencyObject)child).native, ((DependencyObject)parent).native);
962 return true;
964 catch {
965 return false;
969 string error;
971 try {
972 return SetPropertyFromValue (data, parent, parent_data, parent_parent_ptr, pi, child_ptr, child_data, out error);
973 } catch {
974 throw new XamlParseException (2010, String.Format ("{0} does not support {1} as content.", parent, child));
978 private unsafe Type LookupType (Value* top_level, string assembly_name, string full_name)
980 Type res = null;
982 if (assembly_name != null) {
984 // if we're given an explicit assembly
985 // name, try and load it, then get the
986 // type from just that assembly
988 Assembly assembly = null;
989 if (LoadAssembly (assembly_name, out assembly) == AssemblyLoadResult.Success) {
990 res = assembly.GetType (full_name);
991 if (res != null)
992 return res;
994 else {
995 Console.Error.WriteLine ("unable to load assembly for target type.");
998 else {
1000 // if we're not given an explicit
1001 // assembly name, loop over all
1002 // assemblies specified in
1003 // Deployment.Parts looking for the
1004 // type.
1005 foreach (Assembly a in Deployment.Current.Assemblies) {
1006 res = a.GetType (full_name);
1007 if (res != null)
1008 return res;
1011 Assembly assembly = typeof (DependencyObject).Assembly;
1012 res = assembly.GetType (full_name);
1013 if (res != null && res.IsPublic)
1014 return res;
1018 return Application.GetComponentTypeFromName (full_name);
1021 private unsafe void SetCLRPropertyFromString (XamlCallbackData *data, IntPtr target_data, object target, PropertyInfo pi, string value, out string error, out IntPtr unmanaged_value)
1023 unmanaged_value = IntPtr.Zero;
1024 error = null;
1026 object new_value = null;
1027 bool do_set = true;
1029 try {
1030 if (IsExplicitNull (value)) {
1031 Type t = pi.PropertyType;
1032 if (t.IsValueType && !(t.IsGenericType && t.GetGenericTypeDefinition () == typeof (Nullable<>))) {
1033 error = "Unable to set non nullable type to null.";
1034 return;
1036 new_value = null;
1037 } else
1038 new_value = MoonlightTypeConverter.ConvertObject (pi, value, target.GetType ());
1039 } catch {
1040 do_set = false;
1043 if (do_set) {
1044 try {
1045 SetValue (data, target_data, pi, target, new_value);
1046 return;
1047 } catch (Exception ex) {
1048 error = ex.Message;
1049 return;
1054 // lastly, attempt to create an unmanaged Value* object, if one is created, the managed
1055 // parser will create a managed wrapper for the object and call SetPropertyFromValue with
1056 // the managed object
1058 bool result = NativeMethods.value_from_str_with_typename (TypeToMoonType (pi.PropertyType), pi.Name, value, out unmanaged_value);
1059 if (!result) {
1060 error = string.Format ("unable to convert to type {0} from a string", pi.PropertyType);
1064 private string TypeToMoonType (Type t)
1066 if (t == typeof (double))
1067 return "double";
1068 if (t == typeof (bool))
1069 return "bool";
1070 return t.Name;
1074 // TODO: Is it legal to jam the whole metadata right in the string ie: TargetType="clr-namespace:Mono;MyType"
1076 private unsafe Type TypeFromString (XamlCallbackData *data, string str)
1078 string assembly_name = null;
1079 string full_name = str;
1081 int ps = str.IndexOf (':');
1082 if (ps > 0) {
1083 string xmlns = NativeMethods.xaml_uri_for_prefix (data->parser, str.Substring (0, ps));
1084 string name = str.Substring (ps + 1, str.Length - ps -1);
1086 return TypeFromString (data, xmlns, name);
1089 return LookupType (data->top_level, assembly_name, full_name);
1092 private unsafe Type TypeFromString (XamlCallbackData *data, string xmlns, string name)
1094 string clr_namespace = ClrNamespaceFromXmlns (xmlns);
1095 string assembly_name = AssemblyNameFromXmlns (xmlns);
1097 string full_name = string.IsNullOrEmpty (clr_namespace) ? name : clr_namespace + "." + name;
1099 return LookupType (data->top_level, assembly_name, full_name);
1102 private unsafe DependencyProperty DependencyPropertyFromString (XamlCallbackData *data, object otarget, Value* target_parent_ptr, string str_value)
1104 object o = Value.ToObject (null, target_parent_ptr);
1105 Style parent = o as Style;
1107 if (parent == null) {
1108 Console.Error.WriteLine ("DependencyPropertyFromString Parent of target is not a Style. It's a {0}", o);
1109 return null;
1112 Type target_type = parent.TargetType;
1113 if (target_type == null) {
1114 Console.Error.WriteLine ("DependencyPropertyFromString TargetType is null.");
1115 return null;
1119 // Check to see if we have an attached property
1121 int dot = str_value.IndexOf ('.');
1122 if (dot >= 0) {
1123 string type_name = str_value.Substring (0, dot);
1124 str_value= str_value.Substring (++dot, str_value.Length - dot);
1126 target_type = TypeFromString (data, type_name);
1129 Types.Ensure (target_type);
1131 ManagedType mt = Deployment.Current.Types.Find (target_type);
1132 DependencyProperty dp = DependencyProperty.Lookup ((Kind) mt.native_handle, str_value);
1134 return dp;
1137 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)
1139 error = null;
1140 object obj_value = Value.ToObject (null, value_ptr);
1144 if (pi.GetCustomAttributes (typeof (SetPropertyDelayedAttribute), true).Length > 0) {
1145 if ((data->flags & XamlCallbackFlags.SettingDelayedProperty) == 0) {
1146 Value v = *value_ptr;
1147 NativeMethods.xaml_delay_set_property (data->parser, target_data, null, pi.Name, ref v);
1148 return true;
1153 if (obj_value is Binding && target is FrameworkElement) {
1154 FrameworkElement fe = (FrameworkElement) target;
1155 fe.SetBinding (DependencyProperty.Lookup (fe.GetKind (), pi.Name), (Binding) obj_value);
1156 return true;
1159 if (obj_value is StaticResource) {
1160 StaticResource sr = (StaticResource)obj_value;
1161 obj_value = "{StaticResource " + sr.ResourceKey + "}";
1164 if (typeof (IList).IsAssignableFrom (pi.PropertyType) && !(obj_value is IList)) {
1165 // This case is handled in the AddChild code
1166 return true;
1169 if (typeof (ResourceDictionary).IsAssignableFrom (pi.PropertyType) && !(obj_value is ResourceDictionary)) {
1170 // This case is handled in the AddChild code
1171 return true;
1174 string str_value = obj_value as string;
1175 if (str_value != null) {
1176 IntPtr unmanaged_value;
1180 // HACK: This really shouldn't be here, but I don't want to bother putting it in Helper, because that
1181 // code probably should be moved into this file
1183 if (pi.PropertyType == typeof (Type)) {
1184 Type t = TypeFromString (data, str_value);
1185 if (t != null) {
1186 SetValue (data, target_data, pi, target, t);
1187 return true;
1191 if (pi.PropertyType == typeof (DependencyProperty)) {
1192 DependencyProperty dp = DependencyPropertyFromString (data, target, target_parent_ptr, str_value);
1193 if (dp != null) {
1194 SetValue (data, target_data, pi, target, dp);
1195 return true;
1199 if (typeof (System.Windows.Data.Binding).IsAssignableFrom (pi.PropertyType) && MarkupExpressionParser.IsBinding (str_value)) {
1200 MarkupExpressionParser p = new MarkupExpressionParser (null, pi.Name, data->parser, target_data);
1202 string expression = str_value;
1203 obj_value = p.ParseExpression (ref expression);
1205 if (!(obj_value is Binding))
1206 return false;
1208 SetValue (data, target_data, pi, target, obj_value);
1209 return true;
1212 if (MarkupExpressionParser.IsStaticResource (str_value)) {
1213 // FIXME: The NUnit tests show we need to use the parent of the target to resolve
1214 // the StaticResource, but are there any cases where we should use the actual target?
1215 DependencyObject parent = Value.ToObject (null, target_parent_ptr) as DependencyObject;
1216 if (parent == null)
1217 return false;
1218 MarkupExpressionParser p = new MarkupExpressionParser (parent, "", data->parser, target_data);
1219 obj_value = p.ParseExpression (ref str_value);
1220 obj_value = ConvertType (pi, pi.PropertyType, obj_value);
1222 SetValue (data, target_data, pi, target, obj_value);
1223 return true;
1226 SetCLRPropertyFromString (data, target_data, target, pi, str_value, out error, out unmanaged_value);
1228 if (error == null && unmanaged_value != IntPtr.Zero)
1229 obj_value = Value.ToObject (null, unmanaged_value);
1230 else
1231 return error == null;
1232 } else {
1233 obj_value = Value.ToObject (pi.PropertyType, value_ptr);
1236 obj_value = ConvertType (pi, pi.PropertyType, obj_value);
1237 SetValue (data, target_data, pi, target, obj_value);
1239 return true;
1242 private static unsafe void SetValue (XamlCallbackData *data, IntPtr target_data, PropertyInfo pi, object target, object value)
1244 SetterBase sb = target as SetterBase;
1246 if (sb != null)
1247 sb.IsSealed = false;
1249 try {
1250 if (NativeMethods.xaml_is_property_set (data->parser, target_data, pi.Name))
1251 throw new XamlParseException (2033, String.Format ("Cannot specify the value multiple times for property: {0}.", pi.Name));
1253 pi.SetValue (target, value, null);
1255 NativeMethods.xaml_mark_property_as_set (data->parser, target_data, pi.Name);
1257 } finally {
1258 if (sb != null)
1259 sb.IsSealed = true;
1263 private static object ConvertType (MemberInfo pi, Type t, object value)
1265 if (value == null)
1266 return null;
1268 Type valueType = value.GetType ();
1269 if (valueType == t)
1270 return value;
1272 try {
1273 if (t.IsEnum) {
1274 string str_value = value as string;
1275 if (str_value != null)
1276 return Enum.Parse (t, str_value, true);
1277 if (Enum.IsDefined (t, value))
1278 return Enum.ToObject (t, value);
1280 } catch {
1283 TypeConverter converter = Helper.GetConverterFor (pi, t);
1284 if (converter == null) {
1285 try {
1286 converter = new MoonlightTypeConverter (pi == null ? null : pi.Name, t);
1287 } catch {
1288 converter = null;
1292 if (converter != null && converter.CanConvertFrom (value.GetType ()))
1293 return converter.ConvertFrom (value);
1295 try {
1296 if (!valueType.IsSubclassOf (t))
1297 value = Convert.ChangeType (value, t, System.Globalization.CultureInfo.CurrentCulture);
1298 } catch {
1301 // This will just let things fail
1302 return value;
1305 private static string ClrNamespaceFromXmlns (string xmlns)
1307 if (String.IsNullOrEmpty (xmlns))
1308 return null;
1310 int start = xmlns.IndexOf ("clr-namespace:");
1312 if (start < 0)
1313 return null;
1314 start += "clr-namespace:".Length;
1316 int end = xmlns.IndexOf (';', start);
1317 if (end == -1)
1318 end = xmlns.Length;
1320 return xmlns.Substring (start, end - start);
1323 private static string AssemblyNameFromXmlns (string xmlns)
1325 if (String.IsNullOrEmpty (xmlns))
1326 return null;
1328 int start = xmlns.IndexOf ("assembly=");
1329 if (start < 0)
1330 return null;
1332 start += "assembly=".Length;
1333 int end = xmlns.IndexOf (';', start);
1334 if (end == -1)
1335 end = xmlns.Length;
1336 return xmlns.Substring (start, end - start);
1339 private static bool ValidateXmlns (string xmlns)
1341 Uri dummy = null;
1342 if (Uri.TryCreate (xmlns, UriKind.Absolute, out dummy))
1343 return true;
1345 int start = xmlns.IndexOf ("clr-namespace");
1346 int end = start + "clr-namespace".Length;
1347 if (end >= xmlns.Length || xmlns [end] != ':')
1348 return false;
1350 start = xmlns.IndexOf ("assembly");
1351 if (start > 0) {
1352 end = start + "assembly".Length;
1353 if (end >= xmlns.Length || xmlns [end] != '=')
1354 return false;
1357 return true;
1360 private unsafe MethodInfo GetSetMethodForAttachedProperty (Value *top_level, string xmlns, string type_name, string prop_name)
1362 string assembly_name = AssemblyNameFromXmlns (xmlns);
1363 string ns = ClrNamespaceFromXmlns (xmlns);
1365 if (assembly_name == null && !TryGetDefaultAssemblyName (top_level, out assembly_name)) {
1366 Console.Error.WriteLine ("Unable to find an assembly to load type from.");
1367 return null;
1370 Assembly clientlib;
1371 if (LoadAssembly (assembly_name, out clientlib) != AssemblyLoadResult.Success) {
1372 Console.Error.WriteLine ("couldn't load assembly: {0} namespace: {1}", assembly_name, ns);
1373 return null;
1376 Type attach_type = clientlib.GetType (type_name, false);
1377 if (attach_type == null) {
1378 attach_type = Application.GetComponentTypeFromName (type_name);
1379 if (attach_type == null) {
1380 Console.Error.WriteLine ("attach type is null {0} '{1}'", type_name, ns);
1381 return null;
1385 MethodInfo set_method = attach_type.GetMethod (String.Concat ("Set", prop_name), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
1386 return set_method;
1389 private static unsafe object GetObjectValue (object target, IntPtr target_data, string prop_name, IntPtr parser, Value* value_ptr, out string error)
1391 error = null;
1393 IntPtr unmanaged_value = IntPtr.Zero;
1394 object o_value = Value.ToObject (null, value_ptr);
1395 if (error == null && unmanaged_value != IntPtr.Zero)
1396 o_value = Value.ToObject (null, unmanaged_value);
1398 if (o_value is String && MarkupExpressionParser.IsStaticResource ((string) o_value)) {
1399 MarkupExpressionParser mp = new MarkupExpressionParser ((DependencyObject) target, prop_name, parser, target_data);
1400 string str_value = o_value as String;
1401 o_value = mp.ParseExpression (ref str_value);
1404 return o_value;
1407 private static bool IsExplicitNull (string value)
1409 return Regex.IsMatch (value, "^{\\s*x:Null\\s*}");
1412 private PropertyInfo GetContentProperty (Type t)
1414 Type walk = t;
1415 string content_property = null;
1417 while (walk != null) {
1418 content_property = GetContentPropertyNameForType (walk);
1419 if (content_property != null)
1420 break;
1421 walk = walk.BaseType;
1424 if (walk == null || content_property == null)
1425 return null;
1427 PropertyInfo pi = walk.GetProperty (content_property, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy);
1428 return pi;
1431 private string GetContentPropertyNameForType (Type t)
1433 object [] o = t.GetCustomAttributes (typeof (ContentPropertyAttribute), false);
1435 if (o.Length == 0)
1436 return null;
1438 ContentPropertyAttribute cpa = (ContentPropertyAttribute ) o [0];
1439 return cpa.Name;
1442 private string GetContentPropertyName (Type t)
1444 object [] o = t.GetCustomAttributes (typeof (ContentPropertyAttribute), true);
1445 if (o.Length == 0)
1446 return null;
1447 ContentPropertyAttribute cpa = (ContentPropertyAttribute ) o [0];
1449 return cpa.Name;
1454 /// Callbacks invoked by the xaml.cpp C++ parser
1458 #region Callbacks from xaml.cpp
1460 // Proxy so that we return IntPtr.Zero in case of any failures, instead of
1461 // genereting an exception and unwinding the stack.
1463 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)
1465 try {
1466 return LookupObject (data->top_level, parent, xmlns, name, create, is_property, out value);
1467 } catch (Exception ex) {
1468 Console.Error.WriteLine ("ManagedXamlLoader::LookupObject ({0}, {1}, {2}, {3}) failed: {3} ({4}).", (IntPtr) data->top_level, xmlns, create, name, ex.Message, ex.GetType ().FullName);
1469 Console.WriteLine (ex);
1470 value = Value.Empty;
1471 error = new MoonError (ex);
1472 return false;
1476 private void cb_create_gchandle ()
1478 if (!handle.IsAllocated)
1479 handle = GCHandle.Alloc (this);
1483 // Proxy so that we return IntPtr.Zero in case of any failures, instead of
1484 // generating an exception and unwinding the stack.
1486 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)
1488 try {
1489 return SetProperty (data, xmlns, target, target_data, target_parent, prop_xmlns, name, value_ptr, value_data);
1490 } catch (Exception ex) {
1491 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);
1492 Console.Error.WriteLine (ex);
1493 error = new MoonError (ex);
1494 return false;
1498 private unsafe bool cb_import_xaml_xmlns (XamlCallbackData *data, string xmlns, ref MoonError error)
1500 try {
1501 if (!ValidateXmlns (xmlns))
1502 return false;
1503 Application.ImportXamlNamespace (xmlns);
1504 return true;
1505 } catch (Exception ex) {
1506 Console.WriteLine ("Application::ImportXamlNamespace ({0}) threw an exception:\n{1}", xmlns, ex);
1507 error = new MoonError (ex);
1508 return false;
1513 private unsafe string cb_get_content_property_name (XamlCallbackData *data, Value* object_ptr, ref MoonError error)
1515 object obj = Value.ToObject (null, object_ptr);
1517 if (obj == null)
1518 return null;
1520 Type t = obj.GetType ();
1521 return GetContentPropertyName (t);
1525 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)
1527 try {
1528 return AddChild (data, parent_parent, parent_is_property, parent_xmlns, parent, parent_data, child, child_data);
1529 } catch (Exception ex) {
1530 Console.Error.WriteLine (ex);
1531 error = new MoonError (ex);
1532 return false;
1537 #endregion