private IEnumerable<BindingExpressionPart> GetPart(string part)
		{
			part = part.Trim();
			if (part == string.Empty)
				throw new FormatException("Path contains an empty part");

			BindingExpressionPart indexer = null;

			int lbIndex = part.IndexOf('[');
			if (lbIndex != -1)
			{
				int rbIndex = part.LastIndexOf(']');
				if (rbIndex == -1)
					throw new FormatException("Indexer did not contain closing bracket");

				int argLength = rbIndex - lbIndex - 1;
				if (argLength == 0)
					throw new FormatException("Indexer did not contain arguments");

				string argString = part.Substring(lbIndex + 1, argLength);
				indexer = new BindingExpressionPart(this, argString, true);

				part = part.Substring(0, lbIndex);
				part = part.Trim();
			}

			if (part.Length > 0)
				yield return new BindingExpressionPart(this, part);
			if (indexer != null)
				yield return indexer;
		}
        internal void Unapply()
        {
            object sourceObject;

            if (_weakSource != null && _weakSource.TryGetTarget(out sourceObject))
            {
                for (var i = 0; i < _parts.Count - 1; i++)
                {
                    BindingExpressionPart part = _parts[i];

                    if (!part.IsSelf)
                    {
                        part.TryGetValue(sourceObject, out sourceObject);
                    }

                    var inpc = sourceObject as INotifyPropertyChanged;
                    if (inpc != null)
                    {
                        inpc.PropertyChanged -= part.ChangeHandler;
                    }
                }
            }

            _weakSource = null;
            _weakTarget = null;
        }
Esempio n. 3
0
            public void PropertyChanged(object sender, PropertyChangedEventArgs args)
            {
                BindingExpressionPart part = NextPart ?? this;

                string name = args.PropertyName;

                if (!string.IsNullOrEmpty(name))
                {
                    if (part.IsIndexer)
                    {
                        if (name.Contains("["))
                        {
                            if (name != string.Format("{0}[{1}]", part.IndexerName, part.Content))
                            {
                                return;
                            }
                        }
                        else if (name != part.IndexerName)
                        {
                            return;
                        }
                    }
                    else if (name != part.Content)
                    {
                        return;
                    }
                }

                _expression.Apply();
                // Device.BeginInvokeOnMainThread(() => _expression.Apply());
            }
Esempio n. 4
0
        void ParsePath()
        {
            string p = Path.Trim();

            var last = new BindingExpressionPart(this, ".");

            _parts.Add(last);

            if (p[0] == '.')
            {
                if (p.Length == 1)
                {
                    return;
                }

                p = p.Substring(1);
            }

            string[] pathParts = p.Split('.');
            for (var i = 0; i < pathParts.Length; i++)
            {
                foreach (BindingExpressionPart part in GetPart(pathParts[i]))
                {
                    last.NextPart = part;
                    _parts.Add(part);
                    last = part;
                }
            }
        }
        internal void Unapply()
        {
            object sourceObject;

            if (_weakSource != null && _weakSource.TryGetTarget(out sourceObject))
            {
                for (var i = 0; i < _parts.Count - 1; i++)
                {
                    BindingExpressionPart part = _parts[i];

                    if (!part.IsSelf)
                    {
                        part.TryGetValue(sourceObject, out sourceObject);
                    }

                    part.Unsubscribe();
                }
            }

            if (_trackingTemplatedParent)
            {
                BindableObject target = null;
                if (_weakTarget?.TryGetTarget(out target) == true && target is Element elem)
                {
                    elem.TemplatedParentChanged -= OnTargetTemplatedParentChanged;
                }
            }

            _weakSource = null;
            _weakTarget = null;

            ClearAncestryChangeSubscriptions();
        }
Esempio n. 6
0
        bool TryConvert(BindingExpressionPart part, ref object value, Type convertTo, bool toTarget)
        {
            if (value == null)
            {
                return(true);
            }
            if ((toTarget && _targetProperty.TryConvert(ref value)) || (!toTarget && convertTo.IsInstanceOfType(value)))
            {
                return(true);
            }

            object original = value;

            try
            {
                var stringValue = value as string ?? string.Empty;
                // see: https://bugzilla.xamarin.com/show_bug.cgi?id=32871
                // do not canonicalize "*.[.]"; "1." should not update bound BindableProperty
                if (stringValue.EndsWith(".", StringComparison.Ordinal) && DecimalTypes.Contains(convertTo))
                {
                    value = original;
                    return(false);
                }

                // do not canonicalize "-0"; user will likely enter a period after "-0"
                if (stringValue == "-0" && DecimalTypes.Contains(convertTo))
                {
                    value = original;
                    return(false);
                }

                value = Convert.ChangeType(value, convertTo, CultureInfo.InvariantCulture);
                return(true);
            }
            catch (InvalidCastException)
            {
                value = original;
                return(false);
            }
            catch (FormatException)
            {
                value = original;
                return(false);
            }
            catch (OverflowException)
            {
                value = original;
                return(false);
            }
        }
		internal void Unapply()
		{
			object sourceObject;
			if (_weakSource != null && _weakSource.TryGetTarget(out sourceObject))
			{
				for (var i = 0; i < _parts.Count - 1; i++)
				{
					BindingExpressionPart part = _parts[i];

					if (!part.IsSelf)
					{
						part.TryGetValue(sourceObject, out sourceObject);
					}

					part.Unsubscribe();
				}
			}

			_weakSource = null;
			_weakTarget = null;
		}
Esempio n. 8
0
        void ParsePath()
        {
            string p = Path.Trim();

            var last = new BindingExpressionPart(this, ".");

            _parts.Add(last);

            if (p[0] == '.')
            {
                if (p.Length == 1)
                {
                    return;
                }

                p = p.Substring(1);
            }

            string[] pathParts = p.Split(ExpressionSplit);
            for (var i = 0; i < pathParts.Length; i++)
            {
                string part = pathParts[i].Trim();
                if (part == string.Empty)
                {
                    throw new FormatException("Path contains an empty part");
                }

                BindingExpressionPart indexer = null;

                int lbIndex = part.IndexOf("[", StringComparison.Ordinal);
                if (lbIndex != -1)
                {
                    int rbIndex = part.LastIndexOf(']');
                    if (rbIndex == -1)
                    {
                        throw new FormatException("Indexer did not contain closing bracket");
                    }

                    int argLength = rbIndex - lbIndex - 1;
                    if (argLength == 0)
                    {
                        throw new FormatException("Indexer did not contain arguments");
                    }

                    string argString = part.Substring(lbIndex + 1, argLength);
                    indexer = new BindingExpressionPart(this, argString, true);

                    part = part.Substring(0, lbIndex);
                    part = part.Trim();
                }
                if (part.Length > 0)
                {
                    var next = new BindingExpressionPart(this, part);
                    last.NextPart = next;
                    _parts.Add(next);
                    last = next;
                }
                if (indexer != null)
                {
                    last.NextPart = indexer;
                    _parts.Add(indexer);
                    last = indexer;
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        ///     Applies the binding expression to a previously set source or target.
        /// </summary>
        void ApplyCore(object sourceObject, BindableObject target, BindableProperty property, bool fromTarget = false)
        {
            BindingMode mode = Binding.GetRealizedMode(_targetProperty);

            if ((mode == BindingMode.OneWay || mode == BindingMode.OneTime) && fromTarget)
            {
                return;
            }

            bool needsGetter = (mode == BindingMode.TwoWay && !fromTarget) || mode == BindingMode.OneWay || mode == BindingMode.OneTime;
            bool needsSetter = !needsGetter && ((mode == BindingMode.TwoWay && fromTarget) || mode == BindingMode.OneWayToSource);

            object current             = sourceObject;
            BindingExpressionPart part = null;

            for (var i = 0; i < _parts.Count; i++)
            {
                part = _parts[i];

                if (!part.IsSelf && current != null)
                {
                    // Allow the object instance itself to provide its own TypeInfo
                    TypeInfo currentType = current is IReflectableType reflectable?reflectable.GetTypeInfo() : current.GetType().GetTypeInfo();

                    if (part.LastGetter == null || !part.LastGetter.DeclaringType.GetTypeInfo().IsAssignableFrom(currentType))
                    {
                        SetupPart(currentType, part);
                    }

                    if (i < _parts.Count - 1)
                    {
                        part.TryGetValue(current, out current);
                    }
                }

                if (!part.IsSelf &&
                    current != null &&
                    ((needsGetter && part.LastGetter == null) ||
                     (needsSetter && part.NextPart == null && part.LastSetter == null)))
                {
                    BindingDiagnostics.SendBindingFailure(Binding, current, target, property, "Binding", PropertyNotFoundErrorMessage, part.Content, current, target.GetType(), property.PropertyName);
                    break;
                }

                if (part.NextPart != null && (mode == BindingMode.OneWay || mode == BindingMode.TwoWay) &&
                    current is INotifyPropertyChanged inpc)
                {
                    part.Subscribe(inpc);
                }
            }

            Debug.Assert(part != null, "There should always be at least the self part in the expression.");

            if (needsGetter)
            {
                if (part.TryGetValue(current, out object value) || part.IsSelf)
                {
                    value = Binding.GetSourceValue(value, property.ReturnType);
                }
                else
                {
                    value = Binding.FallbackValue ?? property.GetDefaultValue(target);
                }

                if (!TryConvert(ref value, property, property.ReturnType, true))
                {
                    BindingDiagnostics.SendBindingFailure(Binding, current, target, property, "Binding", CannotConvertTypeErrorMessage, value, property.ReturnType);
                    return;
                }

                target.SetValueCore(property, value, SetValueFlags.ClearDynamicResource, BindableObject.SetValuePrivateFlags.Default | BindableObject.SetValuePrivateFlags.Converted);
            }
            else if (needsSetter && part.LastSetter != null && current != null)
            {
                object value = Binding.GetTargetValue(target.GetValue(property), part.SetterType);

                if (!TryConvert(ref value, property, part.SetterType, false))
                {
                    BindingDiagnostics.SendBindingFailure(Binding, current, target, property, "Binding", CannotConvertTypeErrorMessage, value, part.SetterType);
                    return;
                }

                object[] args;
                if (part.IsIndexer)
                {
                    args = new object[part.Arguments.Length + 1];
                    part.Arguments.CopyTo(args, 0);
                    args[args.Length - 1] = value;
                }
                else if (part.IsBindablePropertySetter)
                {
                    args = new[] { part.BindablePropertyField, value };
                }
                else
                {
                    args = new[] { value };
                }

                part.LastSetter.Invoke(current, args);
            }
        }
Esempio n. 10
0
        void SetupPart(TypeInfo sourceType, BindingExpressionPart part)
        {
            part.Arguments  = null;
            part.LastGetter = null;
            part.LastSetter = null;

            PropertyInfo property = null;

            if (part.IsIndexer)
            {
                if (sourceType.IsArray)
                {
                    int index;
                    if (!int.TryParse(part.Content, out index))
                    {
                        Log.Warning("Binding", "{0} could not be parsed as an index for a {1}", part.Content, sourceType);
                    }
                    else
                    {
                        part.Arguments = new object[] { index }
                    };

                    part.LastGetter = sourceType.GetDeclaredMethod("Get");
                    part.LastSetter = sourceType.GetDeclaredMethod("Set");
                    part.SetterType = sourceType.GetElementType();
                }

                DefaultMemberAttribute defaultMember = null;
                foreach (var attrib in sourceType.GetCustomAttributes(typeof(DefaultMemberAttribute), true))
                {
                    if (attrib is DefaultMemberAttribute d)
                    {
                        defaultMember = d;
                        break;
                    }
                }

                string indexerName = defaultMember != null ? defaultMember.MemberName : "Item";

                part.IndexerName = indexerName;

#if NETSTANDARD2_0
                try {
                    property = sourceType.GetDeclaredProperty(indexerName);
                }
                catch (AmbiguousMatchException) {
                    // Get most derived instance of property
                    foreach (var p in sourceType.GetProperties())
                    {
                        if (p.Name == indexerName && (property == null || property.DeclaringType.IsAssignableFrom(property.DeclaringType)))
                        {
                            property = p;
                        }
                    }
                }
#else
                property = sourceType.GetDeclaredProperty(indexerName);
#endif

                if (property == null)                 //is the indexer defined on the base class?
                {
                    property = sourceType.BaseType.GetProperty(indexerName);
                }
                if (property == null)                 //is the indexer defined on implemented interface ?
                {
                    foreach (var implementedInterface in sourceType.ImplementedInterfaces)
                    {
                        property = implementedInterface.GetProperty(indexerName);
                        if (property != null)
                        {
                            break;
                        }
                    }
                }

                if (property != null)
                {
                    ParameterInfo   parameter = null;
                    ParameterInfo[] array     = property.GetIndexParameters();
                    for (int i = 0; i < array.Length; i++)
                    {
                        parameter = array[i];
                        break;
                    }

                    if (parameter != null)
                    {
                        try
                        {
                            object arg = Convert.ChangeType(part.Content, parameter.ParameterType, CultureInfo.InvariantCulture);
                            part.Arguments = new[] { arg };
                        }
                        catch (FormatException)
                        {
                        }
                        catch (InvalidCastException)
                        {
                        }
                        catch (OverflowException)
                        {
                        }
                    }
                }
            }
            else
            {
                TypeInfo type = sourceType;
                while (type != null && property == null)
                {
                    property = type.GetDeclaredProperty(part.Content);
                    type     = type.BaseType?.GetTypeInfo();
                }
            }
            if (property != null)
            {
                if (property.CanRead && property.GetMethod.IsPublic && !property.GetMethod.IsStatic)
                {
                    part.LastGetter = property.GetMethod;
                }
                if (property.CanWrite && property.SetMethod.IsPublic && !property.SetMethod.IsStatic)
                {
                    part.LastSetter = property.SetMethod;
                    var lastSetterParameters = part.LastSetter.GetParameters();
                    part.SetterType = lastSetterParameters[lastSetterParameters.Length - 1].ParameterType;

                    if (Binding.AllowChaining)
                    {
                        FieldInfo bindablePropertyField = sourceType.GetDeclaredField(part.Content + "Property");
                        if (bindablePropertyField != null && bindablePropertyField.FieldType == typeof(BindableProperty) && sourceType.ImplementedInterfaces.Contains(typeof(IElementController)))
                        {
                            MethodInfo setValueMethod = null;
#if NETSTANDARD1_0
                            foreach (MethodInfo m in sourceType.AsType().GetRuntimeMethods())
                            {
                                if (m.Name.EndsWith("IElementController.SetValueFromRenderer"))
                                {
                                    ParameterInfo[] parameters = m.GetParameters();
                                    if (parameters.Length == 2 && parameters[0].ParameterType == typeof(BindableProperty))
                                    {
                                        setValueMethod = m;
                                        break;
                                    }
                                }
                            }
#else
                            setValueMethod = typeof(IElementController).GetMethod("SetValueFromRenderer", new[] { typeof(BindableProperty), typeof(object) });
#endif
                            if (setValueMethod != null)
                            {
                                part.LastSetter = setValueMethod;
                                part.IsBindablePropertySetter = true;
                                part.BindablePropertyField    = bindablePropertyField.GetValue(null);
                            }
                        }
                    }
                }
#if !NETSTANDARD1_0
                TupleElementNamesAttribute tupleEltNames;
                if (property != null &&
                    part.NextPart != null &&
                    property.PropertyType.IsGenericType &&
                    (property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , , , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , , , , ,>)) &&
                    (tupleEltNames = property.GetCustomAttribute(typeof(TupleElementNamesAttribute)) as TupleElementNamesAttribute) != null)
                {
                    //modify the nextPart to access the tuple item via the ITuple indexer
                    var nextPart = part.NextPart;
                    var name     = nextPart.Content;
                    var index    = tupleEltNames.TransformNames.IndexOf(name);
                    if (index >= 0)
                    {
                        nextPart.IsIndexer = true;
                        nextPart.Content   = index.ToString();
                    }
                }
#endif
            }
        }
Esempio n. 11
0
        /// <summary>
        ///     Applies the binding expression to a previously set source or target.
        /// </summary>
        void ApplyCore(object sourceObject, BindableObject target, BindableProperty property, bool fromTarget = false)
        {
            BindingMode mode = Binding.GetRealizedMode(_targetProperty);

            if ((mode == BindingMode.OneWay || mode == BindingMode.OneTime) && fromTarget)
            {
                return;
            }

            bool needsGetter = (mode == BindingMode.TwoWay && !fromTarget) || mode == BindingMode.OneWay || mode == BindingMode.OneTime;
            bool needsSetter = !needsGetter && ((mode == BindingMode.TwoWay && fromTarget) || mode == BindingMode.OneWayToSource);

            object current             = sourceObject;
            object previous            = null;
            BindingExpressionPart part = null;

            for (var i = 0; i < _parts.Count; i++)
            {
                part = _parts[i];
                bool isLast = i + 1 == _parts.Count;

                if (!part.IsSelf && current != null)
                {
                    // Allow the object instance itself to provide its own TypeInfo
                    var reflectable = current as IReflectableType;
                    System.Reflection.TypeInfo currentType = reflectable != null?reflectable.GetTypeInfo() : current.GetType().GetTypeInfo();

                    if (part.LastGetter == null || !part.LastGetter.DeclaringType.GetTypeInfo().IsAssignableFrom(currentType))
                    {
                        SetupPart(currentType, part);
                    }

                    if (!isLast)
                    {
                        part.TryGetValue(current, out current);
                    }
                }

                if (!part.IsSelf && current != null)
                {
                    if ((needsGetter && part.LastGetter == null) || (needsSetter && part.NextPart == null && part.LastSetter == null))
                    {
                        Console.WriteLine("Binding, " + PropertyNotFoundErrorMessage, part.Content, current, target.GetType(), property.PropertyName);
                        break;
                    }
                }

                if (mode == BindingMode.OneWay || mode == BindingMode.TwoWay)
                {
                    var inpc = current as INotifyPropertyChanged;
                    if (inpc != null && !ReferenceEquals(current, previous))
                    {
                        part.Subscribe(inpc);
                    }
                }

                previous = current;
            }

            Debug.Assert(part != null, "There should always be at least the self part in the expression.");

            if (needsGetter)
            {
                object value = property.DefaultValue;
                if (part.TryGetValue(current, out value) || part.IsSelf)
                {
                    value = Binding.GetSourceValue(value, property.ReturnType);
                }
                else
                {
                    value = property.DefaultValue;
                }

                if (!TryConvert(ref value, property.ReturnType, true))
                {
                    Console.WriteLine($"Binding : {value} can not be converted to type {property.ReturnType}");
                    return;
                }

                target.SetValueCore(property, value, SetValueFlags.ClearDynamicResource, BindableObject.SetValuePrivateFlags.Default | BindableObject.SetValuePrivateFlags.Converted, false);
            }
            else if (needsSetter && part.LastSetter != null && current != null)
            {
                object value = Binding.GetTargetValue(target.GetValue(property), part.SetterType);

                if (!TryConvert(ref value, part.SetterType, false))
                {
                    Console.WriteLine($"Binding : {value} can not be converted to type {part.SetterType}");
                    return;
                }

                object[] args;
                if (part.IsIndexer)
                {
                    args = new object[part.Arguments.Length + 1];
                    part.Arguments.CopyTo(args, 0);
                    args[args.Length - 1] = value;
                }
                else if (part.IsBindablePropertySetter)
                {
                    args = new[] { part.BindablePropertyField, value };
                }
                else
                {
                    args = new[] { value };
                }

                part.LastSetter.Invoke(current, args);
            }
        }
Esempio n. 12
0
		IEnumerable<BindingExpressionPart> GetPart(string part)
		{
			part = part.Trim();
			if (part == string.Empty)
				throw new FormatException("Path contains an empty part");

			BindingExpressionPart indexer = null;

			int lbIndex = part.IndexOf('[');
			if (lbIndex != -1)
			{
				int rbIndex = part.LastIndexOf(']');
				if (rbIndex == -1)
					throw new FormatException("Indexer did not contain closing bracket");

				int argLength = rbIndex - lbIndex - 1;
				if (argLength == 0)
					throw new FormatException("Indexer did not contain arguments");

				string argString = part.Substring(lbIndex + 1, argLength);
				indexer = new BindingExpressionPart(this, argString, true);

				part = part.Substring(0, lbIndex);
				part = part.Trim();
			}

			if (part.Length > 0)
				yield return new BindingExpressionPart(this, part);
			if (indexer != null)
				yield return indexer;
		}
Esempio n. 13
0
        void SetupPart(TypeInfo sourceType, BindingExpressionPart part)
        {
            part.Arguments  = null;
            part.LastGetter = null;
            part.LastSetter = null;

            PropertyInfo property = null;

            if (part.IsIndexer)
            {
                if (sourceType.IsArray)
                {
                    if (!int.TryParse(part.Content, out var index))
                    {
                        BindingDiagnostics.SendBindingFailure(Binding, "Binding", ParseIndexErrorMessage, part.Content, sourceType);
                    }
                    else
                    {
                        part.Arguments = new object[] { index }
                    };

                    part.LastGetter = sourceType.GetDeclaredMethod("Get");
                    part.LastSetter = sourceType.GetDeclaredMethod("Set");
                    part.SetterType = sourceType.GetElementType();
                }

                string indexerName = "Item";
                foreach (DefaultMemberAttribute attrib in sourceType.GetCustomAttributes(typeof(DefaultMemberAttribute), true))
                {
                    indexerName = attrib.MemberName;
                    break;
                }

                part.IndexerName = indexerName;

                property = GetIndexer(sourceType, indexerName, part.Content);

                if (property != null)
                {
                    ParameterInfo   parameter = null;
                    ParameterInfo[] array     = property.GetIndexParameters();

                    if (array.Length > 0)
                    {
                        parameter = array[0];
                    }

                    if (parameter != null)
                    {
                        try
                        {
                            object arg = Convert.ChangeType(part.Content, parameter.ParameterType, CultureInfo.InvariantCulture);
                            part.Arguments = new[] { arg };
                        }
                        catch (FormatException)
                        {
                        }
                        catch (InvalidCastException)
                        {
                        }
                        catch (OverflowException)
                        {
                        }
                    }
                }
            }
            else
            {
                TypeInfo type = sourceType;
                while (type != null && property == null)
                {
                    property = type.GetDeclaredProperty(part.Content);
                    type     = type.BaseType?.GetTypeInfo();
                }
            }
            if (property != null)
            {
                if (property.CanRead && property.GetMethod.IsPublic && !property.GetMethod.IsStatic)
                {
                    part.LastGetter = property.GetMethod;
                }
                if (property.CanWrite && property.SetMethod.IsPublic && !property.SetMethod.IsStatic)
                {
                    part.LastSetter = property.SetMethod;
                    var lastSetterParameters = part.LastSetter.GetParameters();
                    part.SetterType = lastSetterParameters[lastSetterParameters.Length - 1].ParameterType;

                    if (Binding.AllowChaining)
                    {
                        FieldInfo bindablePropertyField = sourceType.GetDeclaredField(part.Content + "Property");
                        if (bindablePropertyField != null && bindablePropertyField.FieldType == typeof(BindableProperty) && sourceType.ImplementedInterfaces.Contains(typeof(IElementController)))
                        {
                            MethodInfo setValueMethod = null;
#if NETSTANDARD1_0
                            foreach (MethodInfo m in sourceType.AsType().GetRuntimeMethods())
                            {
                                if (m.Name.EndsWith("IElementController.SetValueFromRenderer"))
                                {
                                    ParameterInfo[] parameters = m.GetParameters();
                                    if (parameters.Length == 2 && parameters[0].ParameterType == typeof(BindableProperty))
                                    {
                                        setValueMethod = m;
                                        break;
                                    }
                                }
                            }
#else
                            setValueMethod = typeof(IElementController).GetMethod("SetValueFromRenderer", new[] { typeof(BindableProperty), typeof(object) });
#endif
                            if (setValueMethod != null)
                            {
                                part.LastSetter = setValueMethod;
                                part.IsBindablePropertySetter = true;
                                part.BindablePropertyField    = bindablePropertyField.GetValue(null);
                            }
                        }
                    }
                }
#if !NETSTANDARD1_0
                if (property != null &&
                    part.NextPart != null &&
                    property.PropertyType.IsGenericType &&
                    (property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , , , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , , , , ,>)) &&
                    property.GetCustomAttribute(typeof(TupleElementNamesAttribute)) is TupleElementNamesAttribute tupleEltNames)
                {
                    //modify the nextPart to access the tuple item via the ITuple indexer
                    var nextPart = part.NextPart;
                    var name     = nextPart.Content;
                    var index    = tupleEltNames.TransformNames.IndexOf(name);
                    if (index >= 0)
                    {
                        nextPart.IsIndexer = true;
                        nextPart.Content   = index.ToString();
                    }
                }
#endif
            }
        }
Esempio n. 14
0
        void SetupPart(TypeInfo sourceType, BindingExpressionPart part)
        {
            part.Arguments  = null;
            part.LastGetter = null;
            part.LastSetter = null;

            PropertyInfo property = null;

            if (part.IsIndexer)
            {
                if (sourceType.IsArray)
                {
                    int index;
                    if (!int.TryParse(part.Content, out index))
                    {
                        Log.Warning("Binding", "{0} could not be parsed as an index for a {1}", part.Content, sourceType);
                    }
                    else
                    {
                        part.Arguments = new object[] { index }
                    };

                    part.LastGetter = sourceType.GetDeclaredMethod("Get");
                    part.LastSetter = sourceType.GetDeclaredMethod("Set");
                    part.SetterType = sourceType.GetElementType();
                }

                DefaultMemberAttribute defaultMember = sourceType.GetCustomAttributes(typeof(DefaultMemberAttribute), true).OfType <DefaultMemberAttribute>().FirstOrDefault();
                string indexerName = defaultMember != null ? defaultMember.MemberName : "Item";

                part.IndexerName = indexerName;

                property = sourceType.GetDeclaredProperty(indexerName);
                if (property == null)                 //is the indexer defined on the base class?
                {
                    property = sourceType.BaseType.GetProperty(indexerName);
                }
                if (property == null)                 //is the indexer defined on implemented interface ?
                {
                    foreach (var implementedInterface in sourceType.ImplementedInterfaces)
                    {
                        property = implementedInterface.GetProperty(indexerName);
                        if (property != null)
                        {
                            break;
                        }
                    }
                }

                if (property != null)
                {
                    ParameterInfo parameter = property.GetIndexParameters().FirstOrDefault();
                    if (parameter != null)
                    {
                        try
                        {
                            object arg = Convert.ChangeType(part.Content, parameter.ParameterType, CultureInfo.InvariantCulture);
                            part.Arguments = new[] { arg };
                        }
                        catch (FormatException)
                        {
                        }
                        catch (InvalidCastException)
                        {
                        }
                        catch (OverflowException)
                        {
                        }
                    }
                }
            }
            else
            {
                property = sourceType.GetDeclaredProperty(part.Content) ?? sourceType.BaseType?.GetProperty(part.Content);
            }

            if (property != null)
            {
                if (property.CanRead && property.GetMethod.IsPublic && !property.GetMethod.IsStatic)
                {
                    part.LastGetter = property.GetMethod;
                }
                if (property.CanWrite && property.SetMethod.IsPublic && !property.SetMethod.IsStatic)
                {
                    part.LastSetter = property.SetMethod;
                    part.SetterType = part.LastSetter.GetParameters().Last().ParameterType;

                    if (Binding.AllowChaining)
                    {
                        FieldInfo bindablePropertyField = sourceType.GetDeclaredField(part.Content + "Property");
                        if (bindablePropertyField != null && bindablePropertyField.FieldType == typeof(BindableProperty) && sourceType.ImplementedInterfaces.Contains(typeof(IElementController)))
                        {
                            MethodInfo setValueMethod = typeof(IElementController).GetMethod("SetValueFromRenderer", new[] { typeof(BindableProperty), typeof(object) });
                            if (setValueMethod != null)
                            {
                                part.LastSetter = setValueMethod;
                                part.IsBindablePropertySetter = true;
                                part.BindablePropertyField    = bindablePropertyField.GetValue(null);
                            }
                        }
                    }
                }

                TupleElementNamesAttribute tupleEltNames;
                if (property != null &&
                    part.NextPart != null &&
                    property.PropertyType.IsGenericType &&
                    (property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , , , ,>) ||
                     property.PropertyType.GetGenericTypeDefinition() == typeof(ValueTuple <, , , , , , ,>)) &&
                    (tupleEltNames = property.GetCustomAttribute(typeof(TupleElementNamesAttribute)) as TupleElementNamesAttribute) != null)
                {
                    //modify the nextPart to access the tuple item via the ITuple indexer
                    var nextPart = part.NextPart;
                    var name     = nextPart.Content;
                    var index    = tupleEltNames.TransformNames.IndexOf(name);
                    if (index >= 0)
                    {
                        nextPart.IsIndexer = true;
                        nextPart.Content   = index.ToString();
                    }
                }
            }
        }
Esempio n. 15
0
			public BindingPair(BindingExpressionPart part, object source, bool isLast)
			{
				Part = part;
				Source = source;
				IsLast = isLast;
			}
Esempio n. 16
0
		bool TryConvert(BindingExpressionPart part, ref object value, Type convertTo, bool toTarget)
		{
			if (value == null)
				return true;
			if ((toTarget && _targetProperty.TryConvert(ref value)) || (!toTarget && convertTo.IsInstanceOfType(value)))
				return true;

			object original = value;
			try
			{
				value = Convert.ChangeType(value, convertTo, CultureInfo.InvariantCulture);
				return true;
			}
			catch (InvalidCastException)
			{
				value = original;
				return false;
			}
			catch (FormatException)
			{
				value = original;
				return false;
			}
			catch (OverflowException)
			{
				value = original;
				return false;
			}
		}
Esempio n. 17
0
		void SetupPart(TypeInfo sourceType, BindingExpressionPart part)
		{
			part.Arguments = null;
			part.LastGetter = null;
			part.LastSetter = null;

			PropertyInfo property = null;
			if (part.IsIndexer)
			{
				if (sourceType.IsArray)
				{
					int index;
					if (!int.TryParse(part.Content, out index))
						Log.Warning("Binding", "{0} could not be parsed as an index for a {1}", part.Content, sourceType);
					else
						part.Arguments = new object[] { index };

					part.LastGetter = sourceType.GetDeclaredMethod("Get");
					part.LastSetter = sourceType.GetDeclaredMethod("Set");
					part.SetterType = sourceType.GetElementType();
				}

				DefaultMemberAttribute defaultMember = sourceType.GetCustomAttributes(typeof(DefaultMemberAttribute), true).OfType<DefaultMemberAttribute>().FirstOrDefault();
				string indexerName = defaultMember != null ? defaultMember.MemberName : "Item";

				part.IndexerName = indexerName;

				property = sourceType.GetDeclaredProperty(indexerName);
				if (property == null)
					property = sourceType.BaseType.GetProperty(indexerName);

				if (property != null)
				{
					ParameterInfo parameter = property.GetIndexParameters().FirstOrDefault();
					if (parameter != null)
					{
						try
						{
							object arg = Convert.ChangeType(part.Content, parameter.ParameterType, CultureInfo.InvariantCulture);
							part.Arguments = new[] { arg };
						}
						catch (FormatException)
						{
						}
						catch (InvalidCastException)
						{
						}
						catch (OverflowException)
						{
						}
					}
				}
			}
			else
			{
				property = sourceType.GetDeclaredProperty(part.Content);
				if (property == null)
					property = sourceType.BaseType.GetProperty(part.Content);
			}

			if (property != null)
			{
				if (property.CanRead && property.GetMethod.IsPublic && !property.GetMethod.IsStatic)
					part.LastGetter = property.GetMethod;
				if (property.CanWrite && property.SetMethod.IsPublic && !property.SetMethod.IsStatic)
				{
					part.LastSetter = property.SetMethod;
					part.SetterType = part.LastSetter.GetParameters().Last().ParameterType;

					if (Binding.AllowChaining)
					{
						FieldInfo bindablePropertyField = sourceType.GetDeclaredField(part.Content + "Property");
						if (bindablePropertyField != null && bindablePropertyField.FieldType == typeof(BindableProperty) && sourceType.ImplementedInterfaces.Contains(typeof(IElementController)))
						{
							MethodInfo setValueMethod = null;
							foreach (MethodInfo m in sourceType.AsType().GetRuntimeMethods())
							{
								if (m.Name.EndsWith("IElementController.SetValueFromRenderer"))
								{
									ParameterInfo[] parameters = m.GetParameters();
									if (parameters.Length == 2 && parameters[0].ParameterType == typeof(BindableProperty))
									{
										setValueMethod = m;
										break;
									}
								}
							}
							if (setValueMethod != null)
							{
								part.LastSetter = setValueMethod;
								part.IsBindablePropertySetter = true;
								part.BindablePropertyField = bindablePropertyField.GetValue(null);
							}
						}
					}
				}
			}
		}
Esempio n. 18
0
		void ParsePath()
		{
			string p = Path.Trim();

			var last = new BindingExpressionPart(this, ".");
			_parts.Add(last);

			if (p[0] == '.')
			{
				if (p.Length == 1)
					return;

				p = p.Substring(1);
			}

			string[] pathParts = p.Split('.');
			for (var i = 0; i < pathParts.Length; i++)
			{
				foreach (BindingExpressionPart part in GetPart(pathParts[i]))
				{
					last.NextPart = part;
					_parts.Add(part);
					last = part;
				}
			}
		}
Esempio n. 19
0
 public BindingPair(BindingExpressionPart part, object source, bool isLast)
 {
     Part   = part;
     Source = source;
     IsLast = isLast;
 }
		private void SetupPart(TypeInfo sourceType, BindingExpressionPart part)
		{
			part.Arguments = null;
			part.LastGetter = null;
			part.LastSetter = null;

			PropertyInfo property = null;
			if (part.IsIndexer)
			{
				if (sourceType.IsArray)
				{
					int index;
					if (!int.TryParse(part.Content, out index))
						Log.Warning("Binding", "{0} could not be parsed as an index for a {1}", part.Content, sourceType);
					else
						part.Arguments = new object[] { index };

					part.LastGetter = sourceType.GetDeclaredMethod("Get");
					part.LastSetter = sourceType.GetDeclaredMethod("Set");
					part.SetterType = sourceType.GetElementType();
				}

				DefaultMemberAttribute defaultMember = sourceType.GetCustomAttributes(typeof(DefaultMemberAttribute), true).OfType<DefaultMemberAttribute>().FirstOrDefault();
				string indexerName = defaultMember != null ? defaultMember.MemberName : "Item";

				part.IndexerName = indexerName;

				property = sourceType.GetDeclaredProperty(indexerName);
				if (property == null)
					property = sourceType.BaseType.GetProperty(indexerName);

				if (property != null)
				{
					ParameterInfo parameter = property.GetIndexParameters().FirstOrDefault();
					if (parameter != null)
					{
						try
						{
							object arg = Convert.ChangeType(part.Content, parameter.ParameterType, CultureInfo.InvariantCulture);
							part.Arguments = new[] { arg };
						}
						catch (FormatException)
						{
						}
						catch (InvalidCastException)
						{
						}
						catch (OverflowException)
						{
						}
					}
				}
			}
			else
			{
				property = sourceType.GetDeclaredProperty(part.Content);
				if (property == null)
					property = sourceType.BaseType.GetProperty(part.Content);
			}

			if (property != null)
			{
				if (property.CanRead && property.GetMethod.IsPublic && !property.GetMethod.IsStatic)
					part.LastGetter = property.GetMethod;
				if (property.CanWrite && property.SetMethod.IsPublic && !property.SetMethod.IsStatic)
				{
					part.LastSetter = property.SetMethod;
					part.SetterType = part.LastSetter.GetParameters().Last().ParameterType;

					if (Binding.AllowChaining)
					{
						FieldInfo bindablePropertyField = sourceType.GetDeclaredField(part.Content + "Property");
						if (bindablePropertyField != null && bindablePropertyField.FieldType == typeof(BindableProperty) && sourceType.ImplementedInterfaces.Contains(typeof(IElementController)))
						{
							MethodInfo setValueMethod = null;
							foreach (MethodInfo m in sourceType.AsType().GetRuntimeMethods())
							{
								if (m.Name.EndsWith("IElementController.SetValueFromRenderer"))
								{
									ParameterInfo[] parameters = m.GetParameters();
									if (parameters.Length == 2 && parameters[0].ParameterType == typeof(BindableProperty))
									{
										setValueMethod = m;
										break;
									}
								}
							}
							if (setValueMethod != null)
							{
								part.LastSetter = setValueMethod;
								part.IsBindablePropertySetter = true;
								part.BindablePropertyField = bindablePropertyField.GetValue(null);
							}
						}
					}
				}
			}
		}