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