// 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));
		}
Example #2
0
        // 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));
        }
Example #3
0
		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)));
        }
Example #5
0
		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);
		}