Esempio n. 1
0
        public object ParseTemplateBinding(ref string expression)
        {
            TemplateBindingExpression tb = new TemplateBindingExpression();

            char   next;
            string prop = GetNextPiece(ref expression, out next);

            tb.SourcePropertyName = prop;
            // tb.Source will be filled in elsewhere between attaching the change handler.

            return(tb);
        }
Esempio n. 2
0
        public override void SetValue(XamlObjectElement obj, object value)
        {
            MutableObject mutable = value as MutableObject;

            if (mutable != null)
            {
                value = mutable.Object;
            }

            Binding binding = value as Binding;

            if (binding != null && SetBinding(binding, Target))
            {
                return;
            }

            if (!typeof(TemplateBindingExpression).IsAssignableFrom(Type))
            {
                TemplateBindingExpression tb = value as TemplateBindingExpression;
                if (tb != null)
                {
                    SetTemplateBinding(tb, Target);
                    return;
                }
            }

            // We do this before lists to cover the case where you are setting a list to a list or
            // a resource dictionary to a resource dictionary, ect
            // as opposed to adding items to the list or dictionary.
            //
            // null is a legal value here because they may have done something like foo="{x:Null}"
            //
            if (value == null || Type.IsAssignableFrom(value.GetType()))
            {
                accessors.Setter(Target, ConvertValue(Type, value));
                return;
            }

            if (typeof(IList).IsAssignableFrom(Type))
            {
                AddToCollection(obj, value);
                return;
            }

            if (typeof(IDictionary).IsAssignableFrom(Type))
            {
                AddToDictionary(obj, value);
                return;
            }

            throw Parser.ParseException("Unable to set property {0} to value {1}.", Name, value);
        }
Esempio n. 3
0
        public override void SetValue(XamlObjectElement obj, object value)
        {
            var mutable = value as MutableObject;

            if (mutable != null)
            {
                value = mutable.Object;
            }

            if (!typeof(Binding).IsAssignableFrom(Type))
            {
                Binding binding = value as Binding;
                if (binding != null)
                {
                    SetBinding(binding, Element.Object);
                    return;
                }
            }

            if (!typeof(TemplateBindingExpression).IsAssignableFrom(Type))
            {
                TemplateBindingExpression tb = value as TemplateBindingExpression;
                if (tb != null)
                {
                    SetTemplateBinding(tb, obj.Object);
                    return;
                }
            }

            if (value == null || Type.IsAssignableFrom(value.GetType()))
            {
                Accessors.Setter(Element.Object, ConvertValue(Type, value));
                return;
            }

            if (typeof(IList).IsAssignableFrom(Type))
            {
                AddToCollection(value);
                return;
            }

            throw new XamlParseException(
                      string.Format("XamlAttachedPropertySetter.SetValue: Could not set value '{0}' to the attached property '{1}.{2}'",
                                    value,
                                    Accessors.DeclaringType,
                                    Accessors.Name)
                      );
        }
        internal void SourcePropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            TemplateBindingExpression target;

            if (this.expression != null)
            {
                target = this.expression.Target as TemplateBindingExpression;
            }
            else
            {
                target = null;
            }
            TemplateBindingExpression templateBindingExpression = target;

            if (templateBindingExpression == null)
            {
                this.Disconnect();
                return;
            }

            templateBindingExpression.SourcePropertyChanged(sender, e.Property);
        }
 internal DependencyPropertyChangedWeakListener(DependencyObject source, TemplateBindingExpression expression)
 {
     this.source            = source;
     this.expression        = new WeakReference(expression);
     this.source.DPChanged += this.SourcePropertyChanged;
 }
Esempio n. 6
0
        public void SetTemplateBinding(TemplateBindingExpression tb, object obj)
        {
            DependencyObject dob = obj as DependencyObject;
            FrameworkElement fwe = obj as FrameworkElement;

            if (dob == null)
            {
                throw Parser.ParseException("Invalid TemplateBinding, expressions must be bound to DependendyObjects.");
            }

            // Applying a {TemplateBinding} to a DO which is not a FrameworkElement should silently discard the binding.
            if (fwe == null)
            {
                return;
            }

            if (Parser.Context == null || Parser.Context.Template == null)
            {
                throw Parser.ParseException("Invalid TemplateBinding, expressions can not be used outside of FrameworkTemplate.");
            }

            FrameworkElement source = Parser.Context.TemplateBindingSource;

            if (source == null)
            {
                throw Parser.ParseException("Invalid TemplateBinding, expression can not be used outside of a FrameworkTemplate.");
            }

            // we don't actually use the type of the source to do property lookups.  TargetType is used for that.
            //
            // For ControlTemplates:
            //     1.  if there is a TargetType, we look up the property on TargetType.
            //     2.  if there isn't a TargetType, we look up the property on typeof (Control).
            // For FrameworkTemplates:
            //     there is no TargetType, so we only look up properties on typeof (FrameworkElement)
            //
            Type            property_lookup_type;
            ControlTemplate template = Parser.Context.Template as ControlTemplate;

            if (template == null)
            {
                return;                 // You can't apply Templatebindings outside of ControlTemplates
            }
            property_lookup_type = template.TargetType ?? typeof(Control);

            DependencyProperty source_prop = LookupDependencyProperty(Deployment.Current.Types.TypeToKind(property_lookup_type), tb.SourcePropertyName);

            if (source_prop == null)
            {
                throw Parser.ParseException("Invalid TemplateBinding, property {0} could not be found.", tb.SourcePropertyName);
            }

            DependencyProperty prop = LookupDependencyProperty();

            if (prop == null)
            {
                var propInfo = property_lookup_type.GetProperty(tb.SourcePropertyName, XamlParser.PROPERTY_BINDING_FLAGS);
                if (!propInfo.PropertyType.IsInstanceOfType(tb))
                {
                    // If there is a CLR property with the correct name and there's no DP registered with that name
                    // we should silently ignore the invalid TemplateBinding
                    return;
                }
                throw Parser.ParseException("Invalid TemplateBinding, property {0} could not be found.", Name);
            }

            tb.TargetProperty = prop;
            tb.SourceProperty = source_prop;

            // If we TemplateBind two incompatible properties we silently discard
            // the TemplateBinding object. Source properties of type object can
            // potentially be of the correct type, so we allow that too.
            if (source_prop.PropertyType == typeof(object) || prop.PropertyType.IsAssignableFrom(source_prop.PropertyType))
            {
                fwe.SetTemplateBinding(prop, tb);
            }
        }