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); }
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); }
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; }
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); } }