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) { DependencyObject dob = target as DependencyObject; object obj_value = Value.ToObject (null, value_ptr); string str_value = obj_value as string; if (str_value == null) return false; if (!str_value.StartsWith ("{")) return false; MarkupExpressionParser p = new SL3MarkupExpressionParser (target, name, data->parser, target_data); string expression = str_value; object o = p.ParseExpression (ref expression); if (o == null) return false; if (o is Binding) { Binding binding = o as Binding; DependencyProperty prop = null; if (dob != null) { string full_type_name = type_name; if (IsAttachedProperty (full_name)) GetNameForAttachedProperty (xmlns, prop_xmlns, full_name, out type_name, out full_type_name); prop = LookupDependencyPropertyForBinding (data, dob, full_type_name, name); if (prop == null && IsAttachedProperty (full_name)) prop = LookupDependencyPropertyForBinding (data, dob, full_name.Split ('.')[0], name); } // If it's null we should look for a regular CLR property if (prop != null) { BindingOperations.SetBinding (dob, prop, binding); return true; } } if (o is TemplateBindingExpression) { // Applying a {TemplateBinding} to a DO which is not a FrameworkElement should silently discard // the binding. if (!(dob is FrameworkElement)) return true; TemplateBindingExpression tb = o as TemplateBindingExpression; IntPtr context = NativeMethods.sl3_xaml_loader_get_context (data->loader); IntPtr source_ptr = NativeMethods.xaml_context_get_template_binding_source (context); // Silently discard TemplateBindings which are not in ControlTemplates FrameworkTemplate source_template = (FrameworkTemplate) NativeDependencyObjectHelper.Lookup (NativeMethods.xaml_context_get_source_template (context)); if (!(source_template is ControlTemplate)) return true; DependencyObject templateSourceObject = NativeDependencyObjectHelper.FromIntPtr (source_ptr) as DependencyObject; if (templateSourceObject == null) return false; DependencyProperty sourceProperty = DependencyProperty.Lookup (templateSourceObject.GetKind(), tb.SourcePropertyName); if (sourceProperty == null) return false; DependencyProperty prop = null; if (dob != null) prop = LookupDependencyPropertyForBinding (data, dob, type_name, name); if (prop == null) return false; tb.TargetProperty = prop; tb.SourceProperty = sourceProperty; ((FrameworkElement) dob).SetTemplateBinding (prop, tb); return true; } if (IsAttachedProperty (full_name)) return TrySetAttachedProperty (data, xmlns, target, target_data, prop_xmlns, full_name, o); PropertyInfo pi = target.GetType ().GetProperty (name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy); o = ConvertType (pi, pi.PropertyType, o); SetValue (data, target_data, pi, target, o); return true; }
private unsafe bool TrySetAttachedProperty (XamlCallbackData *data, string xmlns, object target, IntPtr target_data, string prop_xmlns, string name, Value* value_ptr) { string full_name = name; string type_name = null; string full_type_name = null; name = GetNameForAttachedProperty (xmlns, prop_xmlns, name, out type_name, out full_type_name); if (name == null) return false; string error = null; object o_value = GetObjectValue (target, target_data, name, data->parser, value_ptr, out error); return TrySetAttachedProperty (data, xmlns, target, target_data, prop_xmlns, full_name, o_value); }
private unsafe void SetCLRPropertyFromString (XamlCallbackData *data, IntPtr target_data, object target, PropertyInfo pi, string value, out string error, out IntPtr unmanaged_value) { unmanaged_value = IntPtr.Zero; error = null; object new_value = null; bool do_set = true; try { if (IsExplicitNull (value)) { Type t = pi.PropertyType; if (t.IsValueType && !(t.IsGenericType && t.GetGenericTypeDefinition () == typeof (Nullable<>))) { error = "Unable to set non nullable type to null."; return; } new_value = null; } else new_value = MoonlightTypeConverter.ConvertObject (pi, value, target.GetType ()); } catch { do_set = false; } if (do_set) { try { SetValue (data, target_data, pi, target, new_value); return; } catch (Exception ex) { error = ex.Message; return; } } // // lastly, attempt to create an unmanaged Value* object, if one is created, the managed // parser will create a managed wrapper for the object and call SetPropertyFromValue with // the managed object // bool result = NativeMethods.value_from_str_with_typename (TypeToMoonType (pi.PropertyType), pi.Name, value, out unmanaged_value); if (!result) { error = string.Format ("unable to convert to type {0} from a string", pi.PropertyType); } }
private unsafe DependencyProperty LookupDependencyPropertyForBinding (XamlCallbackData *data, DependencyObject fwe, string type_name, string propertyName) { // map the property name + type_name to an actual DependencyProperty Kind kind; Type type = string.IsNullOrEmpty (type_name) ? null : TypeFromString (data, type_name); if (type != null) { Types.Ensure (type); kind = Deployment.Current.Types.TypeToNativeKind (type); } else { kind = fwe.GetKind (); } if (kind == Kind.INVALID) return null; try { return DependencyProperty.Lookup (kind, propertyName); } catch { return null; } }
private unsafe bool TrySetObjectTextProperty (XamlCallbackData *data, string xmlns, object target, Value* target_ptr, IntPtr target_data, Value* value_ptr, IntPtr value_data) { object obj_value = Value.ToObject (null, value_ptr); string str_value = obj_value as string; if (str_value == null) return false; string assembly_name = AssemblyNameFromXmlns (xmlns); string clr_namespace = ClrNamespaceFromXmlns (xmlns); string type_name = NativeMethods.xaml_get_element_name (data->parser, target_data); string full_name = String.IsNullOrEmpty (clr_namespace) ? type_name : clr_namespace + "." + type_name; Type type = LookupType (data->top_level, assembly_name, full_name); if (type == null || type.IsSubclassOf (typeof (DependencyObject))) return false; // For now just trim the string right here, in the future this should probably be done in the xaml parser object e = ConvertType (null, type, str_value.Trim ()); NativeMethods.value_free_value2 ((IntPtr)target_ptr); unsafe { Value *val = (Value *) target_ptr; GCHandle handle = GCHandle.Alloc (e); val->IsGCHandle = true; val->k = Deployment.Current.Types.TypeToKind (e.GetType ()); val->u.p = GCHandle.ToIntPtr (handle); } return true; }
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) { object parent = Value.ToObject (null, parent_ptr); object child = Value.ToObject (null, child_ptr); if (parent_is_property) { object parent_parent = Value.ToObject (null, parent_parent_ptr); return AddChildToProperty (data, parent_parent, parent_xmlns, parent, child, child_data); } return AddChildToItem (data, parent_parent_ptr, parent, parent_data, child_ptr, child, child_data); }
/// /// /// Callbacks invoked by the xaml.cpp C++ parser /// /// #region Callbacks from xaml.cpp // // Proxy so that we return IntPtr.Zero in case of any failures, instead of // genereting an exception and unwinding the stack. // 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) { value = Value.Empty; try { return LookupObject (data->top_level, parent, xmlns, name, create, is_property, out value); } catch (Exception ex) { NativeMethods.value_free_value (ref value); value = Value.Empty; Console.Error.WriteLine ("ManagedXamlLoader::LookupObject ({0}, {1}, {2}, {3}) failed: {3} ({4}).", (IntPtr) data->top_level, xmlns, create, name, ex.Message, ex.GetType ().FullName); Console.WriteLine (ex); error = new MoonError (ex); return false; } }
private unsafe bool TrySetEventReflection (XamlCallbackData *data, string xmlns, object publisher, string type_name, string name, Value* value_ptr, out string error) { object subscriber = null; EventInfo ie = publisher.GetType ().GetEvent (name); string handler_name = Value.ToObject (null, value_ptr) as string; try { subscriber = Value.ToObject (null, data->top_level); } catch { } //Console.WriteLine ("TrySetEventReflection ({0}, {1}, {2}, {3}, {4}, {5}) handler_name: {6}", data->top_level, xmlns, publisher, type_name, name, value_ptr, handler_name); if (ie == null) { error = "Event does not exist."; return false; } if (handler_name == null) { error = "No method name supplied for event handler."; return false; } MethodInfo invoker_info = ie.EventHandlerType.GetMethod ("Invoke"); ParameterInfo [] event_params = invoker_info.GetParameters (); Delegate d = null; Type stype = subscriber.GetType (); MethodInfo [] methods = stype.GetMethods (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance); MethodInfo candidate = null; bool name_match = false; for (int i = 0; i < methods.Length; i++) { MethodInfo m = methods [i]; ParameterInfo [] parameters; if (m.Name != handler_name) continue; if (name_match) { error = "Multiple candidates with the same name found for event handler."; // Console.WriteLine (error); return false; } name_match = true; if (m.ReturnType != typeof (void)) continue; parameters = m.GetParameters (); if (parameters.Length != event_params.Length) continue; bool match = true; for (int p = 0; p < parameters.Length; p++) { if (!event_params [p].ParameterType.IsSubclassOf (parameters [p].ParameterType) && parameters [p].ParameterType != event_params [p].ParameterType) { Console.WriteLine ("mismatch: {0} and {1}", parameters [p].ParameterType, event_params [p].ParameterType); match = false; break; } } if (!match) continue; if (candidate != null) { error = "Multiple candidates for event handler found."; // Console.WriteLine (error); return false; } candidate = m; } if (candidate == null) { error = "Event handler not found."; // Console.WriteLine (error); return false; } d = Delegate.CreateDelegate (ie.EventHandlerType, subscriber, candidate, false); if (d == null) { 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); error = "Can not create even delegate."; return false; } // 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); error = null; ie.AddEventHandler (publisher, d); return true; }
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) { error = null; object obj_value = Value.ToObject (null, value_ptr); if (pi.GetCustomAttributes (typeof (SetPropertyDelayedAttribute), true).Length > 0) { if ((data->flags & XamlCallbackFlags.SettingDelayedProperty) == 0) { Value v = *value_ptr; NativeMethods.xaml_delay_set_property (data->parser, target_data, null, pi.Name, ref v); return true; } } if (obj_value is Binding && target is FrameworkElement) { FrameworkElement fe = (FrameworkElement) target; fe.SetBinding (DependencyProperty.Lookup (fe.GetKind (), pi.Name), (Binding) obj_value); return true; } if (obj_value is StaticResource) { StaticResource sr = (StaticResource)obj_value; obj_value = "{StaticResource " + sr.ResourceKey + "}"; } if (typeof (IList).IsAssignableFrom (pi.PropertyType) && !(obj_value is IList)) { // This case is handled in the AddChild code return true; } if (typeof (ResourceDictionary).IsAssignableFrom (pi.PropertyType) && !(obj_value is ResourceDictionary)) { // This case is handled in the AddChild code return true; } string str_value = obj_value as string; if (str_value != null) { IntPtr unmanaged_value; if (pi.PropertyType == typeof (Type)) { Type t = TypeFromString (data, str_value); if (t != null) { SetValue (data, target_data, pi, target, t); return true; } } if (pi.PropertyType == typeof (DependencyProperty)) { DependencyProperty dp = DependencyPropertyFromString (data, target, target_parent_ptr, str_value); if (dp != null) { SetValue (data, target_data, pi, target, dp); return true; } } if (typeof (System.Windows.Data.Binding).IsAssignableFrom (pi.PropertyType) && SL3MarkupExpressionParser.IsBinding (str_value)) { MarkupExpressionParser p = new SL3MarkupExpressionParser (null, pi.Name, data->parser, target_data); string expression = str_value; obj_value = p.ParseExpression (ref expression); if (!(obj_value is Binding)) return false; SetValue (data, target_data, pi, target, obj_value); return true; } if (SL3MarkupExpressionParser.IsStaticResource (str_value)) { MarkupExpressionParser p = new SL3MarkupExpressionParser (null, "", data->parser, target_data); obj_value = p.ParseExpression (ref str_value); obj_value = ConvertType (pi, pi.PropertyType, obj_value); SetValue (data, target_data, pi, target, obj_value); return true; } SetCLRPropertyFromString (data, target_data, target, pi, str_value, out error, out unmanaged_value); try { if (error == null && unmanaged_value != IntPtr.Zero) obj_value = Value.ToObject (null, unmanaged_value); else return error == null; } finally { if (unmanaged_value != IntPtr.Zero) Mono.NativeMethods.value_delete_value2 (unmanaged_value); } } else { obj_value = Value.ToObject (pi.PropertyType, value_ptr); } obj_value = ConvertType (pi, pi.PropertyType, obj_value); SetValue (data, target_data, pi, target, obj_value); return true; }
private static unsafe void SetValue (XamlCallbackData *data, IntPtr target_data, PropertyInfo pi, object target, object value) { if (NativeMethods.xaml_is_property_set (data->parser, target_data, pi.Name)) throw new XamlParseException (2033, String.Format ("Cannot specify the value multiple times for property: {0}.", pi.Name)); pi.SetValue (target, value, null); NativeMethods.xaml_mark_property_as_set (data->parser, target_data, pi.Name); }
private unsafe DependencyProperty DependencyPropertyFromString (XamlCallbackData *data, object otarget, Value* target_parent_ptr, string str_value) { object o = Value.ToObject (null, target_parent_ptr); Style parent = o as Style; if (parent == null) { Console.Error.WriteLine ("DependencyPropertyFromString Parent of target is not a Style. It's a {0}", o); return null; } Type target_type = parent.TargetType; if (target_type == null) { Console.Error.WriteLine ("DependencyPropertyFromString TargetType is null."); return null; } // // Check to see if we have an attached property // int dot = str_value.IndexOf ('.'); if (dot >= 0) { string type_name = str_value.Substring (0, dot); str_value= str_value.Substring (++dot, str_value.Length - dot); target_type = TypeFromString (data, type_name); } Types.Ensure (target_type); ManagedType mt = Deployment.Current.Types.Find (target_type); DependencyProperty dp = DependencyProperty.Lookup ((Kind) mt.native_handle, str_value); return dp; }
private unsafe Type TypeFromString (XamlCallbackData *data, string xmlns, string name) { string clr_namespace = ClrNamespaceFromXmlns (xmlns); string assembly_name = AssemblyNameFromXmlns (xmlns); string full_name = string.IsNullOrEmpty (clr_namespace) ? name : clr_namespace + "." + name; return LookupType (data->top_level, assembly_name, full_name); }
// // TODO: Is it legal to jam the whole metadata right in the string ie: TargetType="clr-namespace:Mono;MyType" // private unsafe Type TypeFromString (XamlCallbackData *data, string str) { string assembly_name = null; string full_name = str; int ps = str.IndexOf (':'); if (ps > 0) { string xmlns = NativeMethods.xaml_uri_for_prefix (data->parser, str.Substring (0, ps)); string name = str.Substring (ps + 1, str.Length - ps -1); return TypeFromString (data, xmlns, name); } return LookupType (data->top_level, assembly_name, full_name); }
private unsafe bool TrySetAttachedProperty (XamlCallbackData *data, string xmlns, object target, IntPtr target_data, string prop_xmlns, string name, object o_value) { string type_name = null; string full_type_name = null; name = GetNameForAttachedProperty (xmlns, prop_xmlns, name, out type_name, out full_type_name); var fwe = target as FrameworkElement; if (fwe != null && o_value is Binding) { var dp = LookupDependencyPropertyForBinding (data, fwe, full_type_name, name); ((FrameworkElement) target).SetBinding (dp, (Binding) o_value); return true; } if (name == null) return false; MethodInfo get_method = GetGetMethodForAttachedProperty (data->top_level, prop_xmlns, type_name, full_type_name, name); if (get_method == null) { Console.Error.WriteLine ("get method is null: {0} {1}", String.Concat ("Get", name), prop_xmlns); return false; } // // The Setter might actually want a collection, in this case we grab the old collection with the getter // and then add the new object to the collection // if (typeof (IList).IsAssignableFrom (get_method.ReturnType) && !(o_value is IList)) { if (get_method != null || get_method.GetParameters () == null || get_method.GetParameters ().Length != 1) { IList the_list = (IList) get_method.Invoke (null, new object [] { target }); try { the_list.Add (o_value); return true; } catch { // don't return here, fall through to the ConvertType case below. } } else { // I guess we need to wrap the current value in a collection, or does this error out? Console.WriteLine ("ow god my eye!"); return false; } } MethodInfo set_method = get_method.DeclaringType.GetMethod (String.Concat ("Set", name), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (set_method == null) { Console.Error.WriteLine ("set method is null: {0} {1}", String.Concat ("Set", name), prop_xmlns); return false; } ParameterInfo [] set_params = set_method.GetParameters (); if (set_params == null || set_params.Length < 2) { Console.Error.WriteLine ("set method signature is incorrect."); return false; } o_value = ConvertType (get_method, set_params [1].ParameterType, o_value); set_method.Invoke (null, new object [] {target, o_value}); return true; }
// // Proxy so that we return bool in case of any failures, instead of // generating an exception and unwinding the stack. // 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) { try { return SetProperty (data, xmlns, target, target_data, target_parent, prop_xmlns, name, value_ptr, value_data); } catch (Exception ex) { try { 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); Console.Error.WriteLine (ex); error = new MoonError (ex); return false; } catch { return false; } } }
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) { PropertyInfo pi = target.GetType ().GetProperty (name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (pi == null) { error = "Property does not exist."; return false; } if (!SetPropertyFromValue (data, target, target_data, target_parent_ptr, pi, value_ptr, value_data, out error)) return false; error = null; return true; }
private unsafe bool cb_import_xaml_xmlns (XamlCallbackData *data, string xmlns, ref MoonError error) { try { if (!ValidateXmlns (xmlns)) return false; Application.ImportXamlNamespace (xmlns); return true; } catch (Exception ex) { Console.WriteLine ("Application::ImportXamlNamespace ({0}) threw an exception: {1}", xmlns, ex); error = new MoonError (ex); return false; } }
private unsafe bool TrySetEnumContentProperty (XamlCallbackData *data, string xmlns, object target, Value* target_ptr, IntPtr target_data, Value* value_ptr, IntPtr value_data) { object obj_value = Value.ToObject (null, value_ptr); string str_value = obj_value as string; if (str_value == null) return false; string assembly_name = AssemblyNameFromXmlns (xmlns); string clr_namespace = ClrNamespaceFromXmlns (xmlns); string type_name = NativeMethods.xaml_get_element_name (data->parser, target_data); string full_name = String.IsNullOrEmpty (clr_namespace) ? type_name : clr_namespace + "." + type_name; Type type = LookupType (data->top_level, assembly_name, full_name); if (type == null || !type.IsEnum) return false; object e = Enum.Parse (type, str_value, true); NativeMethods.value_free_value2 ((IntPtr)target_ptr); unsafe { Value *val = (Value *) target_ptr; GCHandle handle = GCHandle.Alloc (e); val->IsGCHandle = true; val->k = Deployment.Current.Types.TypeToKind (e.GetType ()); val->u.p = GCHandle.ToIntPtr (handle); } return true; }
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) { try { return AddChild (data, parent_parent, parent_is_property, parent_xmlns, parent, parent_data, child, child_data); } catch (Exception ex) { Console.Error.WriteLine (ex); error = new MoonError (ex); return false; } }
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) { string error; object target = Value.ToObject (null, target_ptr); if (target == null) { Console.Error.WriteLine ("target is null: {0} {1} {2}", (IntPtr)target_ptr, name, xmlns); return false; } if (name == null) { if (TrySetEnumContentProperty (data, xmlns, target, target_ptr, target_data, value_ptr, value_data)) return true; if (TrySetCollectionContentProperty (xmlns, target, target_ptr, target_data, value_ptr, value_data)) return true; if (TrySetObjectTextProperty (data, xmlns, target, target_ptr, target_data, value_ptr, value_data)) return true; Console.Error.WriteLine ("no property name supplied"); return false; } string full_name = name; int dot = name.IndexOf ('.'); string type_name = null; if (dot >= 0) { type_name = name.Substring (0, dot); if (prop_xmlns != null) { string ns = ClrNamespaceFromXmlns (prop_xmlns); if (ns != null) type_name = String.Concat (ns, ".", type_name); } name = name.Substring (++dot, name.Length - dot); } if (TrySetExpression (data, xmlns, target, target_data, target_parent_ptr, type_name, prop_xmlns, name, full_name, value_ptr, value_data)) return true; if (!IsAttachedProperty (data, target, xmlns, prop_xmlns, full_name)) { if (TrySetPropertyReflection (data, xmlns, target, target_data, target_parent_ptr, type_name, name, value_ptr, value_data, out error)) return true; if (TrySetEventReflection (data, xmlns, target, type_name, name, value_ptr, out error)) return true; } else { if (TrySetAttachedProperty (data, xmlns, target, target_data, prop_xmlns, full_name, value_ptr)) return true; } return false; }
private unsafe bool IsAttachedProperty (XamlCallbackData *data, object target, string xmlns, string prop_xmlns, string name) { string type_name = null; string full_type_name = null; name = GetNameForAttachedProperty (xmlns, prop_xmlns, name, out type_name, out full_type_name); if (name == null) return false; MethodInfo get_method = GetGetMethodForAttachedProperty (data->top_level, prop_xmlns, type_name, full_type_name, name); if (get_method == null) return false; return !target.GetType ().IsSubclassOf (get_method.DeclaringType); }
private unsafe bool AddChildToProperty (XamlCallbackData *data, object parent_parent, string parent_xmlns, object parent, object child, IntPtr child_data) { string full_prop_name = parent as string; if (full_prop_name == null) { Console.Error.WriteLine ("Attempting to add child to non string parent {0} as a property.", parent); return false; } int dot = full_prop_name.IndexOf ('.'); if (dot < 1) return false; string type_name = full_prop_name.Substring (0, dot); string prop_name = full_prop_name.Substring (++dot, full_prop_name.Length - dot); Type target_type = TypeFromString (data, parent_xmlns, type_name); if (target_type == null) { Console.Error.WriteLine ("Type '{0}' with xmlns '{1}' could not be found", type_name, parent_xmlns); return false; } if (!target_type.IsAssignableFrom (parent_parent.GetType ())) { // This would happen with an attached property, we don't need to do anything here....do we? return false; } PropertyInfo pi = parent_parent.GetType ().GetProperty (prop_name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (pi == null) { Console.Error.WriteLine ("Property does not exist. {0}", prop_name); return false; } if (typeof (ResourceDictionary).IsAssignableFrom (pi.PropertyType) && !(child is ResourceDictionary)) { ResourceDictionary the_dict = (ResourceDictionary) pi.GetValue (parent_parent, null); string key_name = NativeMethods.xaml_get_element_key (data->parser, child_data); if (key_name == null) { throw new XamlParseException (2034, "Elements in a ResourceDictionary must have x:Key or x:Name attribute."); } if (the_dict == null) { the_dict = (ResourceDictionary) Activator.CreateInstance (pi.PropertyType); if (the_dict == null) { Console.Error.WriteLine ("Unable to create instance of dictionary: " + pi.PropertyType); return false; } pi.SetValue (parent_parent, the_dict, null); } try { the_dict.Add (key_name, child); return true; } catch (ArgumentException) { throw new XamlParseException (2273, "Elements in the same ResourceDictionary cannot have the same x:Key"); } } if (typeof (IList).IsAssignableFrom (pi.PropertyType) && !(child is IList)) { IList the_list = (IList) pi.GetValue (parent_parent, null); if (the_list == null) { the_list = (IList) Activator.CreateInstance (pi.PropertyType); if (the_list == null) { Console.Error.WriteLine ("Unable to create instance of list: " + pi.PropertyType); return false; } pi.SetValue (parent_parent, the_list, null); } try { the_list.Add (child); return true; } catch (Exception e) { Console.WriteLine (e); return false; } } return true; }
private unsafe bool AddChildToItem (XamlCallbackData *data, Value *parent_parent_ptr, object parent, IntPtr parent_data, Value *child_ptr, object child, IntPtr child_data) { ResourceDictionary the_dict = parent as ResourceDictionary; if (the_dict != null) { string key_name = NativeMethods.xaml_get_element_key (data->parser, child_data); if (key_name == null) { Console.Error.WriteLine ("Attempting to add item to a resource dictionary without an x:Key or x:Name"); throw new XamlParseException (-1, -1, "You must specify an x:Key or x:Name for elements in a ResourceDictionary"); } try { the_dict.Add (key_name, child); return true; } catch (Exception e) { // Fall through to string Console.Error.WriteLine (e); return false; } } IList the_list = parent as IList; if (the_list != null) { try { the_list.Add (child); return true; } catch { return false; } } Type parent_type = parent.GetType (); PropertyInfo pi = GetContentProperty (parent_type); if (pi == null) { Console.Error.WriteLine ("Unable to find content property on type {0}", parent_type); return false; } // // Is the content property a collection // if (typeof (IList).IsAssignableFrom (pi.PropertyType) && !(child is IList)) { the_list = (IList) pi.GetValue (parent, null); if (the_list == null) { the_list = (IList) Activator.CreateInstance (pi.PropertyType); if (the_list == null) { Console.Error.WriteLine ("Unable to create instance of list: " + pi.PropertyType); return false; } pi.SetValue (parent, the_list, null); } try { the_list.Add (child); return true; } catch { return false; } } string error; try { return SetPropertyFromValue (data, parent, parent_data, parent_parent_ptr, pi, child_ptr, child_data, out error); } catch { throw new XamlParseException (2010, String.Format ("{0} does not support {1} as content.", parent, child)); } }