void MentorChanged(object sender, EventArgs e) { try { var mentor = Target.Mentor; if (Binding.RelativeSource != null && Binding.RelativeSource.Mode == RelativeSourceMode.TemplatedParent) { // If we're using a RelativeSource binding and listening to the mentor, it means we should use the // Templateparent itself as the source object. For the case of OneTime bindings we need to refresh // the binding explictly as we won't be listening to the change notification on PropertyPathWalker. if (mentor == null) { PropertyPathWalker.Update(null); } else { PropertyPathWalker.Update(mentor.TemplateOwner); } Refresh(); } else { // If we hit here it means we're databound to the DataContext on our mentor and so we should // be listening for DataContextChanged events on it. SetDataContextSource(mentor); } } catch (Exception ex) { try { Console.WriteLine("Moonlight: Unhandled exception in BindingExpressionBase.MentorChanged: {0}", ex); } catch { // Ignore } } }
internal BindingExpressionBase(Binding binding, DependencyObject target, DependencyProperty property) { Binding = binding; Target = target; Property = property; bool bindsToView = property == FrameworkElement.DataContextProperty || property.PropertyType == typeof(IEnumerable) || property.PropertyType == typeof(ICollectionView); PropertyPathWalker = new PropertyPathWalker(Binding.Path.ParsePath, binding.BindsDirectlyToSource, bindsToView, IsBoundToAnyDataContext); if (Binding.Mode != BindingMode.OneTime) { PropertyPathWalker.IsBrokenChanged += PropertyPathValueChanged; PropertyPathWalker.ValueChanged += PropertyPathValueChanged; } }
internal override void OnDetached(DependencyObject element) { if (!Attached) { return; } base.OnDetached(element); if (TwoWayTextBoxText) { ((TextBox)Target).LostFocus -= TextBoxLostFocus; } var targetFE = element as FrameworkElement; if (IsMentorDataContextBound) { Target.MentorChanged -= MentorChanged; SetDataContextSource(null); } else if (IsParentDataContextBound) { targetFE.VisualParentChanged -= ParentChanged; SetDataContextSource(null); } else if (IsSelfDataContextBound) { SetDataContextSource(null); } targetFE = targetFE ?? Target.Mentor; if (targetFE != null && CurrentError != null) { Validation.RemoveError(targetFE, CurrentError); CurrentError = null; } if (updateDataSourceCallback != null) { Target.RemovePropertyChangedHandler(Property, updateDataSourceCallback); updateDataSourceCallback = null; } PropertyPathWalker.Update(null); }
void DataContextChanged(IntPtr dependency_object, IntPtr propertyChangedEventArgs, ref MoonError error, IntPtr closure) { try { var fe = (FrameworkElement)NativeDependencyObjectHelper.Lookup(dependency_object); PropertyPathWalker.Update(fe.DataContext); // OneTime bindings refresh when the datacontext changes. As these bindings do not listen // for the ValueChanged notifications from the PropertyPathWalker we need to force a refresh if (Binding.Mode == BindingMode.OneTime) { Refresh(); } } catch (Exception ex) { try { error = new MoonError(ex); } catch { } } }
void SetDataContextSource(FrameworkElement fe) { if (DataContextSource != null) { DataContextSource.RemovePropertyChangedHandler(FrameworkElement.DataContextProperty, DataContextChanged); } DataContextSource = fe; if (DataContextSource != null) { DataContextSource.AddPropertyChangedHandler(FrameworkElement.DataContextProperty, DataContextChanged); } // If a FrameworkElement binds to its own datacontext and the VisualParent is null, we end // up here with a null DataContextSource. In this scenario we do not want to update. if (DataContextSource != null || IsMentorDataContextBound) { PropertyPathWalker.Update(DataContextSource == null ? null : DataContextSource.DataContext); } }
void HandleFeTargetLoaded(object sender, RoutedEventArgs e) { // This is only called if we have an ElementName based binding // and could not find the object named by 'ElementName'. This means // that the element has been added to the live tree and has been loaded // so the odds are we should be able to find the named element. FrameworkElement fe = (FrameworkElement)sender; fe.Loaded -= HandleFeTargetLoaded; object source = FindSourceByElementName(); if (source != null) { PropertyPathWalker.Update(source); } Invalidate(); Target.SetValue(Property, this); }
public override object GroupNameFromItem(object item, int level, CultureInfo culture) { object value; if (string.IsNullOrEmpty(PropertyName)) { value = item; } else { PropertyPathWalker = PropertyPathWalker ?? new PropertyPathWalker(PropertyName); value = PropertyPathWalker.GetValue(item); } if (converter != null) { value = converter.Convert(value, typeof(object), level, culture); } return(value); }
void InvalidateAfterMentorChanged(object sender, EventArgs e) { // This is only called if we bound to a DependencyObject with an ElementName // based binding and the DO initially had no mentor. We now have a mentor so // we can do our name lookup. Target.MentorChanged -= InvalidateAfterMentorChanged; object source = FindSourceByElementName(); if (source == null) { Target.Mentor.Loaded += HandleFeTargetLoaded; } else { PropertyPathWalker.Update(source); } Invalidate(); Target.SetValue(Property, this); }
internal BindingExpressionBase (Binding binding, DependencyObject target, DependencyProperty property) { Binding = binding; Target = target; Property = property; bool bindsToView = property == FrameworkElement.DataContextProperty || property.PropertyType == typeof (IEnumerable) || property.PropertyType == typeof (ICollectionView); PropertyPathWalker = new PropertyPathWalker (Binding.Path.ParsePath, binding.BindsDirectlyToSource, bindsToView, IsBoundToAnyDataContext); if (Binding.Mode != BindingMode.OneTime) { PropertyPathWalker.IsBrokenChanged += PropertyPathValueChanged; PropertyPathWalker.ValueChanged += PropertyPathValueChanged; } }
internal BindingExpressionBase (Binding binding, DependencyObject target, DependencyProperty property) { Binding = binding; Target = target; Property = property; mentorDataContextChangedCallback = OnNativeMentorDataContextChangedSafe; bool bindsToView = property == FrameworkElement.DataContextProperty || property.PropertyType == typeof (IEnumerable) || property.PropertyType == typeof (ICollectionView); PropertyPathWalker = new PropertyPathWalker (Binding.Path.Path, binding.BindsDirectlyToSource, bindsToView); if (Binding.Mode != BindingMode.OneTime) PropertyPathWalker.ValueChanged += PropertyPathValueChanged; }
// This is the object we're databound to void CalculateDataSource() { object source = null; // There are four possible ways to get the source: // Binding.Source, Binding.ElementName, Binding.RelativeSource and finally the fallback to DataContext. // Only one of the first three will be non-null if (Binding.Source != null) { PropertyPathWalker.Update(Binding.Source); } else if (Binding.ElementName != null) { // If we 'Target' in a custom DP it's possible // 'Target' won't be able to find the ElementName. // In this case we just use the Mentor and hope. source = FindSourceByElementName(); // When doing ElementName bindings we need to know when we've been // added to the live tree in order to invalidate the binding and do // the name lookup again. If we can't find a mentor and Target isn't // a FrameworkElement, we need to wait for the mentor to be attached // and then do the lookup when it's loaded. var feTarget = Target as FrameworkElement ?? Target.Mentor; if (feTarget == null) { Target.MentorChanged += InvalidateAfterMentorChanged; } else { feTarget.Loaded += HandleFeTargetLoaded; } PropertyPathWalker.Update(source); } else if (Binding.RelativeSource != null && Binding.RelativeSource.Mode == RelativeSourceMode.Self) { PropertyPathWalker.Update(Target); } else { // If we've bound to a FrameworkElements own DataContext property or the ContentProperty, we need // to read the datacontext of the parent element. var fe = Target as FrameworkElement; if (fe != null && (Property == FrameworkElement.DataContextProperty || Property == ContentPresenter.ContentProperty)) { fe.VisualParentChanged += ParentChanged; fe = (FrameworkElement)fe.VisualParent; SetDataContextSource(fe); } else { if (fe == null) { Target.MentorChanged += MentorChanged; fe = Target.Mentor; } if (fe != null && Binding.RelativeSource != null && Binding.RelativeSource.Mode == RelativeSourceMode.TemplatedParent) { PropertyPathWalker.Update(fe.TemplateOwner); } else { SetDataContextSource(fe); } } } }