示例#1
0
        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
                }
            }
        }
示例#2
0
        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;
            }
        }
示例#3
0
        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);
        }
示例#4
0
 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 {
         }
     }
 }
示例#5
0
        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);
            }
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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);
        }
示例#9
0
		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;
			}
		}
示例#10
0
		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;
		}
示例#11
0
        // 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);
                    }
                }
            }
        }