// It expects that it is not invoked when there is no value to // assign. // When it is passed null, then it returns a default instance. // For example, passing null as Int32 results in 0. // But do not immediately try to instantiate with the type, since the type might be abstract. object DoGetCorrectlyTypedValue (XamlMember xm, XamlType xt, object value) { if (value == null) { if (xt.IsContentValue (service_provider)) // it is for collection/dictionary key and item return null; else return xt.IsNullable ? null : xt.Invoker.CreateInstance (new object [0]); } if (xt == null) return value; // Not sure if this is really required though... var vt = sctx.GetXamlType (value.GetType ()); if (vt.CanAssignTo (xt)) return value; // FIXME: this could be generalized by some means, but I cannot find any. if (xt.UnderlyingType == typeof (XamlType) && value is string) value = ResolveTypeFromName ((string) value); // FIXME: this could be generalized by some means, but I cannot find any. if (xt.UnderlyingType == typeof (Type)) value = new TypeExtension ((string) value).ProvideValue (service_provider); if (xt == XamlLanguage.Type && value is string) value = new TypeExtension ((string) value); if (IsAllowedType (xt, value)) return value; var xtc = xm?.TypeConverter ?? xt.TypeConverter; if (xtc != null && value != null) { var tc = xtc.ConverterInstance; if (tc != null && tc.CanConvertFrom (value.GetType ())) value = tc.ConvertFrom (service_provider, null, value); return value; } throw new XamlObjectWriterException (String.Format ("Value '{0}' (of type {1}) is not of or convertible to type {0} (member {3})", value, value != null ? (object) value.GetType () : "(null)", xt, xm)); }
// It expects that it is not invoked when there is no value to // assign. // When it is passed null, then it returns a default instance. // For example, passing null as Int32 results in 0. // But do not immediately try to instantiate with the type, since the type might be abstract. object DoGetCorrectlyTypedValue(XamlMember xm, XamlType xt, object value) { if (value == null) { if (xt.IsContentValue(service_provider)) // it is for collection/dictionary key and item { return(null); } else { return(xt.IsNullable ? null : xt.Invoker.CreateInstance(new object [0])); } } if (xt == null) { return(value); } // Not sure if this is really required though... var vt = sctx.GetXamlType(value.GetType()); if (vt.CanAssignTo(xt)) { return(value); } // FIXME: this could be generalized by some means, but I cannot find any. if (xt.UnderlyingType == typeof(XamlType) && value is string) { value = ResolveTypeFromName((string)value); } // FIXME: this could be generalized by some means, but I cannot find any. if (xt.UnderlyingType == typeof(Type)) { value = new TypeExtension((string)value).ProvideValue(service_provider); } if (xt == XamlLanguage.Type && value is string) { value = new TypeExtension((string)value); } if (IsAllowedType(xt, value)) { return(value); } var xtc = (xm != null ? xm.TypeConverter : null) ?? xt.TypeConverter; if (xtc != null && value != null) { var tc = xtc.ConverterInstance; if (tc != null && tc.CanConvertFrom(value.GetType())) { value = tc.ConvertFrom(value); } return(value); } throw new XamlObjectWriterException(String.Format("Value '{0}' (of type {1}) is not of or convertible to type {0} (member {3})", value, value != null ? (object)value.GetType() : "(null)", xt, xm)); }
public override void WriteStartObject (XamlType xamlType) { if (xamlType == null) throw new ArgumentNullException ("xamlType"); manager.StartObject (); var xm = members.Count > 0 ? members.Peek () : null; var pstate = xm != null ? object_states.Peek () : null; var wpl = xm != null && xm != XamlLanguage.Items ? pstate.WrittenProperties : null; if (wpl != null && wpl.Contains (xm)) throw new XamlDuplicateMemberException (String.Format ("Property '{0}' is already set to this '{1}' object", xm, pstate.Type)); var cstate = new ObjectState () {Type = xamlType, IsInstantiated = false}; object_states.Push (cstate); if (!xamlType.IsContentValue ()) // FIXME: there could be more conditions e.g. the type requires Arguments. InitializeObjectIfRequired (true); if (wpl != null) // note that this adds to the *owner* object's properties. wpl.Add (xm); }
// It expects that it is not invoked when there is no value to // assign. // When it is passed null, then it returns a default instance. // For example, passing null as Int32 results in 0. // But do not immediately try to instantiate with the type, since the type might be abstract. object GetCorrectlyTypedValue(XamlMember xm, XamlType xt, object value, bool fallbackToString = false) { try { if (value == null) { if (xt.IsContentValue(service_provider)) // it is for collection/dictionary key and item { return(null); } else { return(xt.IsNullable ? null : xt.Invoker.CreateInstance(new object[0])); } } if (ReferenceEquals(xt, null)) { return(value); } // Not sure if this is really required though... var vt = sctx.GetXamlType(value.GetType()); if (vt.CanAssignTo(xt)) { return(value); } // FIXME: this could be generalized by some means, but I cannot find any. if (xt.UnderlyingType == typeof(XamlType) && value is string) { value = ResolveTypeFromName((string)value); } // FIXME: this could be generalized by some means, but I cannot find any. if (xt.UnderlyingType == typeof(Type)) { value = new TypeExtension((string)value).ProvideValue(service_provider); } if (ReferenceEquals(xt, XamlLanguage.Type) && value is string) { value = new TypeExtension((string)value); } if (IsAllowedType(xt, value)) { return(value); } var xtc = xm?.TypeConverter ?? xt.TypeConverter; if (xtc != null && value != null) { var tc = xtc.ConverterInstance; if (tc != null && tc.CanConvertFrom(service_provider, value.GetType())) { value = tc.ConvertFrom(service_provider, CultureInfo.InvariantCulture, value); } return(value); } } catch (Exception ex) { // For + ex.Message, the runtime should print InnerException message like .NET does. throw new XamlObjectWriterException(String.Format("Could not convert object \'{0}' (of type {1}) to {2}: ", value, value != null ? (object)value.GetType() : "(null)", xt) + ex.Message, ex); } return(fallbackToString ? value : throw new XamlObjectWriterException(String.Format("Value '{0}' (of type {1}) is not of or convertible to type {2} (member {3})", value, value != null ? (object)value.GetType() : "(null)", xt, xm))); }
public override void WriteStartObject (XamlType xamlType) { if (xamlType == null) throw new ArgumentNullException ("xamlType"); manager.StartObject (); var xm = members.Count > 0 ? members.Peek () : null; var pstate = xm != null ? object_states.Peek () : null; var wpl = xm == null || xm.Type.IsCollection || xm.Type.IsDictionary ? null : pstate.WrittenProperties; if (wpl != null && wpl.Contains (xm)) throw new XamlDuplicateMemberException (String.Format ("Property '{0}' is already set to this '{1}' object", xm, pstate.Type)); var cstate = new ObjectState () {Type = xamlType, IsInstantiated = false}; object_states.Push (cstate); if (!xamlType.IsContentValue (service_provider)) InitializeObjectIfRequired (true); if (wpl != null) // note that this adds to the *owner* object's properties. wpl.Add (xm); }