示例#1
0
        private void BuildBinding(Expression <Func <TTargetMember> > bindTarget, Expression <Func <TSourceMember> > bindSource, Func <TSourceMember, TTargetMember> valueConverter, bool applyLeft)
        {
            _targetReference = bindTarget.Body as MemberExpression;
            _sourceReference = bindSource.Body as MemberExpression;

            if (_targetReference == null)
            {
                throw new ArgumentException($"{nameof(bindTarget)} is expected to contain a MemberExpression, instead it got {bindTarget.Body.NodeType}.");
            }
            if (_sourceReference == null)
            {
                throw new ArgumentException($"{nameof(bindSource)} is expected to contain a MemberExpression, instead it got {bindSource.Body.NodeType}.");
            }

            _targetInstance = ExpressionHelper.EvaluateExpression(_targetReference.Expression);
            _sourceInstance = ExpressionHelper.EvaluateExpression(_sourceReference.Expression) as INotifyPropertyChanged;

            if (bindTarget == null)
            {
                throw new ArgumentException($"{nameof(bindTarget)} must be the member of an instance.");
            }
            if (_sourceInstance == null)
            {
                throw new ArgumentException($"{nameof(bindSource)} must be the member of an instance that implements {nameof(INotifyPropertyChanged)}.");
            }

            _targetProperty = BindManager.GetBindEndpoint(_targetInstance).GetMemberAsTarget(_targetReference.Member, this);
            _sourceProperty = BindManager.GetBindEndpoint(_sourceInstance).GetMemberAsSource(_sourceReference.Member, this);

            if (valueConverter == null)
            {
                // Default just directly applies the value of bindSource to bindTarget
                ApplyToTargetCall = Expression.Lambda <Action>(Expression.Assign(_targetReference, _sourceReference)).Compile();
            }
            else
            {
                // Converter was provided so we package it into an Action to call later
                Action <TTargetMember> setTargetAction   = ExpressionHelper.MakeAssignmentAction <TTargetMember>(_targetProperty.SetMethod, _targetInstance);
                Func <TSourceMember>   getSourceFunction = ExpressionHelper.MakeGetFunc <TSourceMember>(_sourceProperty.GetMethod, _sourceInstance);

                ApplyToTargetCall = () => setTargetAction.Invoke(valueConverter(getSourceFunction()));
            }

            _sourceInstance.PropertyChanged += (sender, e) => {
                if (_sourceProperty.Name == e.PropertyName && this.Enabled)
                {
                    Run();
                }
            };

            _enabled = true;

            if (applyLeft)
            {
                Run();
            }
        }
 /// <summary>
 /// Gets a list of all bindings where a member of this instance is the target of the bind.
 /// </summary>
 public static IReadOnlyCollection <Binding> GetTargetedBindings(this INotifyPropertyChanged instance)
 {
     return(BindManager.GetBindEndpoint(instance).CachedMembers.SelectMany(d => d.Value.TargetBindings).ToList <Binding>().AsReadOnly());
 }