Example #1
0
        public static PropertyPath <TValue> Create <TValue>(Expression <Func <TValue> > propertyExpression)
        {
            var          path          = PropertyPathVisitor.GetPath(propertyExpression);
            var          propertyInfos = path.Cast <PropertyInfo>().ToArray();
            var          parts         = new PathProperty[propertyInfos.Length];
            PathProperty previous      = null;

            for (int i = 0; i < propertyInfos.Length; i++)
            {
                var propertyInfo = propertyInfos[i];
                var item         = new PathProperty(previous, propertyInfo);
                parts[i] = item;
                previous = item;
            }

            var constants = ConstantVisitor.GetConstants(propertyExpression);

            if (!constants.Any())
            {
                throw new ArgumentException("Expression contains no constants", nameof(propertyExpression));
            }

            //valuePath.Source = source;
            var source       = constants.Last().Value;
            var propertyPath = new PropertyPath(parts);

            return(new PropertyPath <TValue>(propertyPath, source));
        }
Example #2
0
        public NotifyingPathItem(INotifyingPathItem previous, PathProperty pathProperty)
        {
            Ensure.NotNull(pathProperty, nameof(pathProperty));
            if (previous?.PathProperty != null)
            {
                var type = previous.PathProperty.PropertyInfo.PropertyType;
                if (type.IsValueType)
                {
                    var message = string.Format(
                        "Property path cannot have structs in it. Copy by value will make subscribing error prone." + Environment.NewLine +
                        "The type {0} is a value type not so {1}.{2} will not notify when it changes.",
                        type.PrettyName(),
                        previous.PathProperty.PropertyInfo,
                        pathProperty.PropertyInfo.Name);
                    throw new ArgumentException(message, nameof(pathProperty));
                }

                if (!typeof(INotifyPropertyChanged).IsAssignableFrom(type))
                {
                    var message = string.Format(
                        "All levels in the path must implement INotifyPropertyChanged." + Environment.NewLine +
                        "The type {0} does not so {1}.{2} will not notify when it changes.",
                        type.PrettyName(),
                        previous.PathProperty.PropertyInfo,
                        pathProperty.PropertyInfo.Name);
                    throw new ArgumentException(message, nameof(pathProperty));
                }
            }

            this.PathProperty             = pathProperty;
            this.onNext                   = x => this.OnPropertyChanged(x.Sender, x.EventArgs);
            this.onError                  = this.OnError;
            this.PropertyChangedEventArgs = new PropertyChangedEventArgs(this.PathProperty.PropertyInfo.Name);
            this.Previous                 = previous;
            var notifyingPathItem = previous as NotifyingPathItem;

            if (notifyingPathItem != null)
            {
                notifyingPathItem.Next = this;
            }

            if (previous != null)
            {
                this.Source = (INotifyPropertyChanged)previous.Value;
            }
        }
Example #3
0
        public static PropertyPath <TSource, TValue> Create <TSource, TValue>(Expression <Func <TSource, TValue> > propertyExpression)
        {
            var          path          = PropertyPathVisitor.GetPath(propertyExpression);
            var          propertyInfos = path.Cast <PropertyInfo>().ToArray();
            var          parts         = new PathProperty[propertyInfos.Length];
            PathProperty previous      = null;

            for (int i = 0; i < propertyInfos.Length; i++)
            {
                var propertyInfo = propertyInfos[i];
                var item         = new PathProperty(previous, propertyInfo);
                parts[i] = item;
                previous = item;
            }

            return(new PropertyPath <TSource, TValue>(new PropertyPath(parts)));
        }
Example #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PathProperty"/> class.
        /// </summary>
        /// <param name="previous"></param>
        /// <param name="propertyInfo">
        /// The property info.
        /// </param>
        public PathProperty(PathProperty previous, PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
            {
                throw new ArgumentNullException(nameof(propertyInfo));
            }

            if (!propertyInfo.CanRead)
            {
                throw new ArgumentException("Propert must be readable");
            }

            this.Previous = previous;
            if (previous != null)
            {
                previous.Next = this;
            }

            this.PropertyInfo = propertyInfo;
        }