private void Subscribe() { INotifyPropertyChanged subject = this.Subject; if (subject == null) { return; } for (int i = 0; i < this.AccessNode.Children.Count; i++) { PropertyAccessNode propertyNode = (PropertyAccessNode)this.AccessNode.Children[i]; WeakPropertyChangedEventManager.Register( subject, propertyNode.Property.Name, this, (me, sender, args) => me.OnPropertyChanged(sender, args)); } if (this.Children != null) { for (int i = 0; i < this.Children.Count; i++) { this.Children[i].UpdateSubject(subject); } } }
public SubscriptionNode(Action <TListener, object> subscriberCallback, PropertyAccessNode propertyAccessNode) { _children = new List <SubscriptionNode>(); _subscriberCallback = subscriberCallback; _propertyAccessNode = propertyAccessNode; _onChangedCallback = OnPropertyChanged; _onChangingCallback = OnPropertyChanging; BuildChildren(); }
private void Unsubscribe() { INotifyPropertyChanged subject = this.Subject; if (subject == null) { return; } for (int i = 0; i < this.AccessNode.Children.Count; i++) { PropertyAccessNode propertyNode = (PropertyAccessNode)this.AccessNode.Children[i]; WeakPropertyChangedEventManager.Unregister(subject, propertyNode.Property.Name, this, null); } if (this.Children != null) { for (int i = 0; i < this.Children.Count; i++) { this.Children[i].Unsubscribe(); } } }
private static void BuildBranches(Expression expression, PropertyAccessTree tree, Stack <PropertyAccessTreeNode> current_node_branch, Predicate <Type> type_filter) { BinaryExpression binaryExpression = expression as BinaryExpression; if (binaryExpression != null) { BuildBranches(binaryExpression.Left, tree, current_node_branch, type_filter); BuildBranches(binaryExpression.Right, tree, current_node_branch, type_filter); return; } UnaryExpression unaryExpression = expression as UnaryExpression; if (unaryExpression != null) { BuildBranches(unaryExpression.Operand, tree, current_node_branch, type_filter); return; } MethodCallExpression methodCallExpression = expression as MethodCallExpression; if (methodCallExpression != null) { foreach (Expression argument in methodCallExpression.Arguments) { BuildBranches(argument, tree, current_node_branch, type_filter); } return; } ConditionalExpression conditionalExpression = expression as ConditionalExpression; if (conditionalExpression != null) { BuildBranches(conditionalExpression.Test, tree, current_node_branch, type_filter); BuildBranches(conditionalExpression.IfTrue, tree, current_node_branch, type_filter); BuildBranches(conditionalExpression.IfFalse, tree, current_node_branch, type_filter); return; } InvocationExpression invocationExpression = expression as InvocationExpression; if (invocationExpression != null) { foreach (Expression argument in invocationExpression.Arguments) { BuildBranches(argument, tree, current_node_branch, type_filter); } BuildBranches(invocationExpression.Expression, tree, current_node_branch, type_filter); return; } switch (expression.NodeType) { case ExpressionType.MemberAccess: MemberExpression memberExpression = (MemberExpression)expression; PropertyInfo property = memberExpression.Member as PropertyInfo; FieldInfo fieldInfo = memberExpression.Member as FieldInfo; if (property != null) { PropertyAccessNode node = new PropertyAccessNode(property); current_node_branch.Push(node); BuildBranches(memberExpression.Expression, tree, current_node_branch, type_filter); } else if (fieldInfo != null) { if (type_filter(fieldInfo.FieldType)) { ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression; if (constantExpression.Value != null) { object value = fieldInfo.GetValue(constantExpression.Value); ConstantNode constantNode = new ConstantNode((INotifyPropertyChanged)value); current_node_branch.Push(constantNode); AddBranch(tree, current_node_branch); } } else { current_node_branch.Clear(); } } else { BuildBranches(memberExpression.Expression, tree, current_node_branch, type_filter); } break; case ExpressionType.Parameter: ParameterExpression parameterExpression = (ParameterExpression)expression; ParameterNode parameterNode = new ParameterNode(expression.Type, parameterExpression.Name); current_node_branch.Push(parameterNode); AddBranch(tree, current_node_branch); break; case ExpressionType.Constant: { ConstantExpression constantExpression = (ConstantExpression)expression; if (type_filter(constantExpression.Type) && constantExpression.Value != null) { ConstantNode constantNode = new ConstantNode((INotifyPropertyChanged)constantExpression.Value); current_node_branch.Push(constantNode); AddBranch(tree, current_node_branch); } else { current_node_branch.Clear(); } } break; case ExpressionType.New: { NewExpression newExpression = (NewExpression)expression; foreach (Expression argument in newExpression.Arguments) { BuildBranches(argument, tree, current_node_branch, type_filter); } } break; case ExpressionType.MemberInit: { MemberInitExpression memberInitExpression = (MemberInitExpression)expression; BuildBranches(memberInitExpression.NewExpression, tree, current_node_branch, type_filter); foreach (var memberBinding in memberInitExpression.Bindings) { MemberAssignment assignment = memberBinding as MemberAssignment; if (assignment != null) { BuildBranches(assignment.Expression, tree, current_node_branch, type_filter); } } } break; default: throw new InvalidProgramException(string.Format("CLINQ does not support expressions of type: {0}", expression.NodeType)); } }