示例#1
0
        /// <summary>
        /// Raises this object's PropertyChanged event for one property and all its dependent
        /// properties.
        /// </summary>
        /// <param name="propertyName">The name of the property that has a new value.</param>
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            // Verify that the notified property actually exists in the current object. This can
            // reveal misspelled properties and missing notifications. It's only checked in Debug
            // builds for performance and stability reasons.
#if DEBUG
            if (!TypeDescriptor.GetProperties(this).OfType <PropertyDescriptor>().Any(d => d.Name == propertyName))
            {
                throw new ArgumentException("Notifying a change of non-existing property " + this.GetType().Name + "." + propertyName);
            }
#endif

            // Call On…Changed methods that are marked with the [PropertyChangedHandler] attribute
            foreach (var changeHandler in PropertyChangedHandlers.GetValuesOrEmpty(propertyName))
            {
                changeHandler();
            }

            // Raise PropertyChanged event, if there is a handler listening to it
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }

            // Also notify changes for dependent properties
            // (This could be moved inside the (handler != null) check for improved performance, but
            // then it could miss out On…Changed method calls for dependent properties, which might
            // be a nice feature.)
            foreach (var dependentPropertyName in DependentNotifications.GetValuesOrEmpty(propertyName))
            {
                OnPropertyChanged(dependentPropertyName);
            }
        }
示例#2
0
        /// <summary>
        ///     Raises this object's PropertyChanged event.
        /// </summary>
        private void RaisePropertyChanged(string propertyName, bool notifyDependentProperties,
                                          IDictionary <string, object> processedProperties,
                                          IDictionary <ICommand, object> processedCommands)
        {
            if (processedProperties.ContainsKey(propertyName))
            {
                return;
            }

            var eventArgs = new PropertyChangedEventArgs(propertyName);

            if (PropertyChanged != null)
            {
                Dispatch(() => PropertyChanged(this, eventArgs));
            }

// ReSharper disable AssignNullToNotNullAttribute
            processedProperties.Add(propertyName, null);
// ReSharper restore AssignNullToNotNullAttribute

            if (!notifyDependentProperties)
            {
                return;
            }

            if (DependentNotifications.TryGetValue(propertyName, out var dependentPropertyNotifications))
            {
                foreach (var dependentProperty in dependentPropertyNotifications)
                {
                    RaisePropertyChanged(dependentProperty, true, processedProperties, processedCommands);
                }
            }

            if (DependentCommandNotifications.TryGetValue(propertyName, out var dependendCommandNotifications))
            {
                foreach (var dependentCommand in dependendCommandNotifications)
                {
                    if (processedCommands.ContainsKey(dependentCommand))
                    {
                        continue;
                    }

                    if (dependentCommand is RelayCommand relayCommand)
                    {
                        relayCommand.RaiseCanExecuteChanged();
                    }

// ReSharper disable AssignNullToNotNullAttribute
                    processedCommands.Add(dependentCommand, null);
// ReSharper restore AssignNullToNotNullAttribute
                }
            }
        }
示例#3
0
        /// <summary>
        ///     Adds a new entry to the list of dependent property notifications.
        /// </summary>
        /// <typeparam name="TSource">the type of the source property</typeparam>
        /// <typeparam name="TDepend">the type of the dependent property</typeparam>
        public virtual void AddPropertyChangedNotification <TSource, TDepend>(
            Expression <Func <TSource> > sourcePropertyAccessor,
            params Expression <Func <TDepend> >[] dependentPropertyAccessors)
        {
            var basePropertyName = GetPropertyName(sourcePropertyAccessor);

            foreach (var dependentPropertyName in dependentPropertyAccessors
                     .Select(GetPropertyName)
                     .Where(dependentPropertyName => basePropertyName != dependentPropertyName))
            {
                if (!DependentNotifications.TryGetValue(basePropertyName, out var notifications))
                {
                    notifications = new List <string>();
                    DependentNotifications.Add(basePropertyName, notifications);
                }

                notifications.Add(dependentPropertyName);
            }
        }
示例#4
0
        public void OnPropertyChanged([CallerMemberName] string property = "")
        {
#if DEBUG
            if (!TypeDescriptor.GetProperties(this).OfType <PropertyDescriptor>().Any(d => d.Name == property))
            {
                throw new ArgumentException("Notifying a change of non-existing property " + GetType().Name + "." + property);
            }
#endif

            if (PropertyChanged != null)
            {
                InvokeOnMainThread(() => PropertyChanged(this, new PropertyChangedEventArgs(property)));
            }

            foreach (string dependentProperty in DependentNotifications.GetValuesOrEmpty(property))
            {
                OnPropertyChanged(dependentProperty);
            }
        }