public static string GetBindingPath(this BindableObject self, BindableProperty property)
        {
            BindingBase binding = GetBinding(self, property);

            if (binding is Xamarin.Forms.Internals.TypedBindingBase)
            {
                var _handlersField = binding.GetType().GetField("_handlers", BindingFlags.Instance | BindingFlags.NonPublic);
                if (_handlersField is not null)
                {
                    //PropertyChangedProxy
                    if (_handlersField.GetValue(binding) is Array array)
                    {
                        if (array.Length > 1)
                        {
                            if (Debugger.IsAttached)
                            {
                                Debugger.Break();
                            }
                        }
                        if (array.Length > 0)
                        {
                            var propertyChangedProxy = array.GetValue(0);
                            var PropertyName         = propertyChangedProxy.GetType().GetProperty("PropertyName", BindingFlags.Instance | BindingFlags.Public);
                            return(PropertyName.GetValue(propertyChangedProxy)?.ToString());
                        }
                    }
                }
            }
            return(null);
        }
예제 #2
0
        BindingBase CopyBinding(BindingBase target)
        {
            BindingBase b;

            if (target != null)
            {
                b = (BindingBase)Activator.CreateInstance(target.GetType());
            }
            else
            {
                b = new Binding();
            }

            foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(target))
            {
                if (pd.IsReadOnly)
                {
                    if (pd.Name.Equals("Bindings", StringComparison.Ordinal))
                    {
                        var bindings    = (Collection <BindingBase>)pd.GetValue(target);
                        var newBindings = (Collection <BindingBase>)pd.GetValue(b);

                        foreach (var binding in bindings)
                        {
                            newBindings.Add(CopyBinding(binding));
                        }
                    }

                    continue;
                }
                try
                {
                    var val1 = pd.GetValue(b);
                    var val2 = pd.GetValue(target);
                    if (object.Equals(val1, val2))
                    {
                        continue;
                    }
                    pd.SetValue(b, val2);
                }
                catch
                {
                }
            }

            return(b);
        }
예제 #3
0
        private DumbBinding(BindingBase bindingToSource, DumbBindingTarget target)
        {
            if (bindingToSource == null)
            {
                throw new ArgumentNullException("bindingToSource");
            }
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }

            this.BindingToSource           = bindingToSource;
            this.Target                    = target;
            target.PropertyChangedCallback = this.OnTargetPropertyChanged;

            BindingMode? bindingMode = null;
            Binding      bindingToSourceAsBinding;
            MultiBinding bindingToSourceAsMultiBinding;

            if ((bindingToSourceAsBinding = bindingToSource as Binding) != null)
            {
                bindingMode = bindingToSourceAsBinding.Mode;
                this.SourcePropertyChangedHandle = PropertyChangedHandle.GetDistinctInstance(bindingToSourceAsBinding, this.OnSourceValueChanged);
                this.UpdateTarget(this.SourcePropertyChangedHandle.PropertyValue, false);
            }
            else if ((bindingToSourceAsMultiBinding = bindingToSource as MultiBinding) != null)
            {
                bindingMode = bindingToSourceAsMultiBinding.Mode;
                this.SourceMultiPropertyChangedHandle = MultiPropertyChangedHandle.GetDistinctInstance(bindingToSourceAsMultiBinding.Bindings.Cast <Binding>().ToArray(),
                                                                                                       this.OnSourceValuesChanged);
                this.UpdateTarget(this.MultiConvert(this.GetSourceValues()), false);
            }
            else
            {
                throw new NotSupportedException(String.Format("Binding type {0} not supported.", bindingToSource.GetType()));
            }

            if (bindingMode == BindingMode.OneWayToSource)
            {
                this.UpdateSource();
            }
        }
예제 #4
0
        private static bool DoesBindingRead(BindingBase binding)
        {
            Binding      bindingAsBinding;
            MultiBinding bindingAsMultiBinding;

            if ((bindingAsBinding = binding as Binding) != null)
            {
                return(PropertyChangedHandle.DoesBindingRead(bindingAsBinding));
            }
            else if ((bindingAsMultiBinding = binding as MultiBinding) != null)
            {
                return(bindingAsMultiBinding.Mode == BindingMode.Default || bindingAsMultiBinding.Mode == BindingMode.OneWay || bindingAsMultiBinding.Mode == BindingMode.TwoWay);
            }

            throw new NotSupportedException(String.Format("Binding type {0} not supported.", binding.GetType()));
        }
예제 #5
0
            public static void Emulate(Binding multiBinding, BindingBase binding)
            {
                if (!(binding is Binding single))
                {
                    throw new NotSupportedException($"{ nameof ( MultiBindingEmulator ) } does not support bindings of type { binding?.GetType ( ).Name ?? "null" }.");
                }

                multiBinding.Converter = new SingleBinding(multiBinding, single);

                multiBinding.Path   = single.Path;
                multiBinding.Mode   = single.Mode;
                multiBinding.Source = single.Source;
                multiBinding.UpdateSourceEventName = single.UpdateSourceEventName;
                multiBinding.FallbackValue         = single.FallbackValue;
                multiBinding.TargetNullValue       = single.TargetNullValue;
            }
예제 #6
0
        private static BindingBase ConstructBinding(Intellibox source, BindingBase template, string propertyName)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

            if (string.IsNullOrEmpty(propertyName))
            {
                throw new ArgumentOutOfRangeException("propertyName", "Cannot be null or empty.");
            }

            if (template == null)
            {
                return new Binding(propertyName)
                       {
                           Source = source
                       }
            }
            ;

            if (!(template is Binding) && !(template is MultiBinding) && !(template is PriorityBinding))
            {
                throw new ArgumentOutOfRangeException("template", "Unrecognized BindingBase: " + template.GetType().ToString());
            }

            var bind = CloneHelper.Clone(template);

            if (bind is Binding)
            {
                ValidateAndSetSource(source, bind as Binding, propertyName);
            }
            else if (bind is MultiBinding)
            {
                var a = bind as MultiBinding;
                // all of these binding have already been cloned, so its safe to set them back to themselves
                for (int i = 0; i < a.Bindings.Count; i++)
                {
                    a.Bindings[i] = ConstructBinding(source, a.Bindings[i], propertyName);
                }
            }
            else if (bind is PriorityBinding)
            {
                var a = bind as PriorityBinding;
                // all of these binding have already been cloned, so its safe to set them back to themselves
                for (int i = 0; i < a.Bindings.Count; i++)
                {
                    a.Bindings[i] = ConstructBinding(source, a.Bindings[i], propertyName);
                }
            }

            return(bind);
        }
예제 #7
0
        public static BindingBase Clone(BindingBase original)
        {
            if (original is Binding)
            {
                return(Clone(original as Binding));
            }
            else if (original is MultiBinding)
            {
                return(Clone(original as MultiBinding));
            }
            else if (original is PriorityBinding)
            {
                return(Clone(original as PriorityBinding));
            }

            throw new ArgumentOutOfRangeException("original", "Unrecognized type: " + original.GetType().ToString());
        }
예제 #8
0
        public static string GetBindingIdentifyerString(BindingBase binding)
        {
            if (binding == null)
            {
                throw new ArgumentNullException("binding");
            }

            Binding      bindingAsBinding;
            MultiBinding bindingAsMultiBinding;

            if ((bindingAsBinding = binding as Binding) != null)
            {
                string elementName;
                if (bindingAsBinding.ElementName != null)
                {
                    elementName = bindingAsBinding.ElementName;
                }
                else if (bindingAsBinding.RelativeSource != null)
                {
                    elementName = String.Format("{{RelativeSource Mode={0}, AncestorLevel={1}, AncestorType={2}}}",
                                                bindingAsBinding.RelativeSource.Mode,
                                                bindingAsBinding.RelativeSource.AncestorLevel,
                                                bindingAsBinding.RelativeSource.AncestorType);
                }
                else if (bindingAsBinding.Source != null)
                {
                    elementName = String.Concat('{', bindingAsBinding.Source.ToString(), '}');
                }
                else
                {
                    elementName = "Self";
                }

                return(String.Format("{{Binding Source={0}, Path={1}}}", elementName, bindingAsBinding.Path.Path));
            }
            else if ((bindingAsMultiBinding = binding as MultiBinding) != null)
            {
                return(String.Format("{{MultiBinding {0}}}", String.Join(", ", bindingAsMultiBinding.Bindings.Select(b => GetBindingIdentifyerString(b)))));
            }

            throw new NotSupportedException(String.Format("Binding type {0} not supported.", binding.GetType()));
        }
예제 #9
0
        private BindingBase GetModifiedBinding(BindingBase binding)
        {
            Binding      bindingAsBinding;
            MultiBinding bindingAsMultiBinding;

            if ((bindingAsBinding = binding as Binding) != null)
            {
                if (bindingAsBinding.ElementName != null)
                {
                    return(bindingAsBinding.Clone(this.FrameworkElement.FindName(bindingAsBinding.ElementName)));
                }
                else if (bindingAsBinding.RelativeSource != null)
                {
                    return(bindingAsBinding.Clone(bindingAsBinding.RelativeSource.Resolve(this.FrameworkElement)));
                }
                else if (bindingAsBinding.Source != null)
                {
                    return(bindingAsBinding.Clone());
                }
                else if (this.SourceSelectorCallback != null)
                {
                    return(bindingAsBinding.Clone(this.SourceSelectorCallback(this)));
                }
                else
                {
                    return(bindingAsBinding.Clone(this.FrameworkElement));
                }
            }
            else if ((bindingAsMultiBinding = binding as MultiBinding) != null)
            {
                var          bindings = bindingAsMultiBinding.Bindings.ToList();
                MultiBinding result   = bindingAsMultiBinding.Clone();
                result.Bindings.Clear();
                result.AddBindings(bindings.Select(b => this.GetModifiedBinding(b)));

                return(result);
            }

            throw new NotSupportedException(String.Format("Binding type {0} not supported.", binding.GetType()));
        }
예제 #10
0
        internal static void GetBindingElementsFromBinding(BindingBase markupExtension,
                                                           IServiceProvider serviceProvider,
                                                           out DependencyObject targetDependencyObject,
                                                           out DependencyProperty targetDependencyProperty)
        {
            targetDependencyObject   = null;
            targetDependencyProperty = null;

            var provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;

            if (provideValueTarget == null)
            {
                return;
            }

            var targetObject = provideValueTarget.TargetObject;

            if (targetObject == null)
            {
                return;
            }

            var type           = targetObject.GetType();
            var targetProperty = provideValueTarget.TargetProperty;

            if (targetProperty != null)
            {
                targetDependencyProperty = targetProperty as DependencyProperty;
                if (targetDependencyProperty != null)
                {
                    targetDependencyObject = targetObject as DependencyObject;
                }
                else
                {
                    var memberInfo = targetProperty as MemberInfo;
                    if (memberInfo != null)
                    {
                        var propertyInfo = memberInfo as PropertyInfo;
                        if (propertyInfo != null)
                        {
                            var schemaContextProvider =
                                serviceProvider.GetService(typeof(IXamlSchemaContextProvider)) as IXamlSchemaContextProvider;
                            if (schemaContextProvider != null)
                            {
                                throw new Exception();
                            }
                        }
                        var c = !(propertyInfo != null) ? ((MethodBase)memberInfo).GetParameters()[1].ParameterType : propertyInfo.PropertyType;
                        if (!typeof(MarkupExtension).IsAssignableFrom(c) || !c.IsAssignableFrom(markupExtension.GetType()))
                        {
                            throw new System.Windows.Markup.XamlParseException(__SR.Get("MarkupExtensionDynamicOrBindingOnClrProp",
                                                                                        markupExtension.GetType().Name, memberInfo.Name, type.Name));
                        }
                    }
                    else if (!typeof(BindingBase).IsAssignableFrom(markupExtension.GetType()) || !typeof(Collection <BindingBase>).IsAssignableFrom(targetProperty.GetType()))
                    {
                        throw new System.Windows.Markup.XamlParseException(__SR.Get("MarkupExtensionDynamicOrBindingInCollection",
                                                                                    markupExtension.GetType().Name, targetProperty.GetType().Name));
                    }
                }
            }
            else if (!typeof(BindingBase).IsAssignableFrom(markupExtension.GetType()) || !typeof(Collection <BindingBase>).IsAssignableFrom(type))
            {
                throw new System.Windows.Markup.XamlParseException(__SR.Get("MarkupExtensionDynamicOrBindingInCollection",
                                                                            markupExtension.GetType().Name, type.Name));
            }
        }
예제 #11
0
        public static void SetMode(this BindingBase subject, BindingMode mode)
        {
            if (subject == null)
            {
                throw new ArgumentNullException("subject");
            }

            Binding      subjectAsBinding;
            MultiBinding subjectAsMultiBinding;

            if ((subjectAsBinding = subject as Binding) != null)
            {
                subjectAsBinding.Mode = mode;
            }
            else if ((subjectAsMultiBinding = subject as MultiBinding) != null)
            {
                foreach (var binding in subjectAsMultiBinding.Bindings)
                {
                    SetMode(binding, mode);
                }
            }
            else
            {
                throw new NotSupportedException(String.Format("The binding type {0} is not supported for cloning.", subject.GetType()));
            }
        }