Ejemplo n.º 1
0
        /// <summary>
        /// Evaluates the specified expression in the context of specified control.
        /// </summary>
        public object Evaluate(ValueBindingExpression expression, DotvvmProperty property, DotvvmBindableControl contextControl)
        {
            var visitor = EvaluateDataContextPath(contextControl);

            // evaluate the final expression
            EvaluateBinding(visitor, expression.Expression, expression.GetViewModelPathExpression(contextControl, property));
            return visitor.Result;
        }
        /// <summary>
        /// Gets the view model path expression.
        /// </summary>
        public override string GetViewModelPathExpression(DotvvmBindableControl control, DotvvmProperty property)
        {
            // find the parent markup control and calculate number of DataContext changes
            int numberOfDataContextChanges;
            var current = control.GetClosestControlBindingTarget(out numberOfDataContextChanges) as DotvvmBindableControl;

            current.EnsureControlHasId();
            return string.Join(".", Enumerable.Range(0, numberOfDataContextChanges).Select(i => "_parent").Concat(new[] { "_controlState_" + current.ID, Expression }));
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Gets all data context on the path to root
 /// </summary>
 public static object[] GetDataContexts(DotvvmBindableControl contextControl, bool seeThis)
 {
     var context = seeThis ? contextControl.GetValue(DotvvmBindableControl.DataContextProperty, false) : null;
     return
         (context == null ? new object[0] : new[] { context })
         .Concat(contextControl.GetAllAncestors().OfType<DotvvmBindableControl>()
         .Where(c => c.properties.ContainsKey(DotvvmBindableControl.DataContextProperty))
         .Select(c => c.GetValue(DotvvmBindableControl.DataContextProperty, false)))
         .ToArray();
 }
        /// <summary>
        /// Translates the expression to client script.
        /// </summary>
        public override string TranslateToClientScript(DotvvmBindableControl control, DotvvmProperty property)
        {
            ValidateExpression(Expression);

            // find the parent markup control and calculate number of DataContext changes
            int numberOfDataContextChanges;
            var current = control.GetClosestControlBindingTarget(out numberOfDataContextChanges) as DotvvmBindableControl;

            current.EnsureControlHasId();
            return string.Join(".", Enumerable.Range(0, numberOfDataContextChanges).Select(i => "$parent").Concat(new[] { "$controlState()", current.ID + "()", Expression }));
        }
Ejemplo n.º 5
0
 public void Add(string name, DotvvmBindableControl control, DotvvmProperty property, Action nullBindingAction)
 {
     var binding = control.GetValueBinding(property);
     if (binding == null)
     {
         nullBindingAction();
     }
     else
     {
         info.Add(new KnockoutBindingInfo() { Name = name, Expression = control.GetValueBinding(property).GetKnockoutBindingExpression() });
     }
 }
Ejemplo n.º 6
0
 protected object ExecDelegate(DotvvmBindableControl contextControl, bool seeThis, bool setRootControl = false)
 {
     var dataContexts = GetDataContexts(contextControl, seeThis);
     var control = setRootControl ? GetRootControl(contextControl) : null;
     try
     {
         return Delegate(dataContexts, control);
     }
     catch (NullReferenceException)
     {
         return null;
     }
 }
        /// <summary>
        /// Evaluates the specified expression.
        /// </summary>
        public override object Evaluate(DotvvmBindableControl control, DotvvmProperty property)
        {
            ValidateExpression(Expression);

            // find the parent markup control and calculate number of DataContext changes
            int numberOfDataContextChanges;
            var current = control.GetClosestControlBindingTarget(out numberOfDataContextChanges) as DotvvmBindableControl;

            if (current == null || !current.RequiresControlState)
            {
                throw new Exception("The {controlState: ...} binding can only be used in a markup control that supports ControlState!");    // TODO: exception handling
            }
            else
            {
                object value;
                return current.ControlState.TryGetValue(Expression, out value) ? value : DefaultValue;
            }
        }
        public override object Evaluate(DotvvmBindableControl control, DotvvmProperty property)
        {
            // I can execute the delegate, or find the property and get its value
            // TODO: whats better ??
            return ExecDelegate(control, property != DotvvmBindableControl.DataContextProperty, setRootControl: true);


            //// find the parent markup control and calculate number of DataContext changes
            //int numberOfDataContextChanges;
            //var current = control.GetClosestControlBindingTarget(out numberOfDataContextChanges);

            //// get the property
            //var sourceProperty = DotvvmProperty.ResolveProperty(current.GetType(), OriginalString);
            //if (sourceProperty == null)
            //{
            //    throw new Exception(string.Format("The markup control of type '{0}' does not have a property '{1}'!", current.GetType(), ExpressionTree));        // TODO: exception handling
            //}

            //// check whether the property contains binding
            //if (current is DotvvmBindableControl)
            //{
            //    var originalBinding = ((DotvvmBindableControl)current).GetBinding(sourceProperty);
            //    if (originalBinding != null && originalBinding.GetType() == typeof(ValueBindingExpression))
            //    {
            //        // ValueBindingExpression must be modified to be evaluated against the original DataContext
            //        return new ValueBindingExpression(string.Join(".",
            //            Enumerable.Repeat("$parent", numberOfDataContextChanges)
            //            .Concat(new[] { originalBinding.OriginalString })));
            //    }
            //    else if (originalBinding != null)
            //    {
            //        return originalBinding;
            //    }
            //}

            //// otherwise evaluate on server
            //return current.GetValue(sourceProperty);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Evaluates the data context path and returns the visitor with hierarchy.
        /// </summary>
        private ExpressionEvaluationVisitor EvaluateDataContextPath(DotvvmBindableControl contextControl)
        {
            // get the hierarchy of DataContext the control is in
            var dataContexts = contextControl.GetAllAncestors().OfType<DotvvmBindableControl>()
                .Select(c => new { Binding = c.GetBinding(DotvvmBindableControl.DataContextProperty, false), Control = c })
                .Where(b => b.Binding != null)
                .ToList();

            // evaluate the DataContext path
            var viewRoot = contextControl.GetRoot();
            var visitor = new ExpressionEvaluationVisitor(GetRootDataContext(viewRoot), viewRoot) { AllowMethods = AllowMethods };
            for (var i = dataContexts.Count - 1; i >= 0; i--)
            {
                var binding = dataContexts[i].Binding;
                if (!(binding is ValueBindingExpression))
                {
                    throw new Exception("The DataContext property can only contain value bindings!"); // TODO: exception handling
                }
                var pathExpression = ((ValueBindingExpression)binding).GetViewModelPathExpression(dataContexts[i].Control, DotvvmBindableControl.DataContextProperty);
                EvaluateBinding(visitor, binding.Expression, pathExpression);
            }
            return visitor;
        }
Ejemplo n.º 10
0
 private DotvvmControl GetRootControl(DotvvmBindableControl control)
 {
     return control.GetClosestControlBindingTarget();
 }
Ejemplo n.º 11
0
 protected void ExecUpdateDelegate(DotvvmBindableControl contextControl, object value, bool seeThis, bool setRootControl = false)
 {
     var dataContexts = GetDataContexts(contextControl, seeThis);
     var control = setRootControl ? GetRootControl(contextControl) : null;
     UpdateDelegate(dataContexts, control, value);
 }
 public override object Evaluate(DotvvmBindableControl control, DotvvmProperty property)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Updates the viewModel with the new value.
 /// </summary>
 public virtual void UpdateSource(object value, DotvvmBindableControl control, DotvvmProperty property)
 {
     ExecUpdateDelegate(control, value, property != DotvvmBindableControl.DataContextProperty);
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Evaluates the binding.
 /// </summary>
 public virtual object Evaluate(DotvvmBindableControl control, DotvvmProperty property)
 {
     return ExecDelegate(control, property != DotvvmBindableControl.DataContextProperty);
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Updates the value.
 /// </summary>
 public override void UpdateSource(object value, DotvvmBindableControl control, DotvvmProperty property)
 {
     control.ControlState[property.Name] = value;
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Evaluates the PropertyInfo for the expression.
        /// </summary>
        public PropertyInfo EvaluateProperty(ValueBindingExpression expression, DotvvmProperty property, DotvvmBindableControl control, out object target)
        {
            var visitor = EvaluateDataContextPath(control);
            target = visitor.Result;

            // evaluate the final expression
            var node = ParseBinding(expression.Expression);
            string propertyName = null;
            if (node is IdentifierNameSyntax)
            {
                propertyName = ((IdentifierNameSyntax)node).ToString();
            }
            else if (node is MemberAccessExpressionSyntax)
            {
                target = visitor.Visit(((MemberAccessExpressionSyntax)node).Expression);
                propertyName = ((MemberAccessExpressionSyntax)node).Name.ToString();
            }

            if (propertyName != null && !visitor.IsSpecialPropertyName(propertyName))
            {
                var propertyInfo = target.GetType().GetProperty(propertyName);
                if (propertyInfo != null)
                {
                    return propertyInfo;
                }
            }
            throw new NotSupportedException(string.Format("Cannot update the source of the binding '{0}'!", expression.Expression));
        }
 public override object Evaluate(DotvvmBindableControl control, DotvvmProperty property)
 {
     return ExecDelegate(control, true, true);
 }
Ejemplo n.º 18
0
        /// <summary>
        /// Finds the binding of the specified type on the specified viewmodel path.
        /// </summary>
        private FindBindingResult FindControlCommandBinding(string[] path, string commandId, DotvvmControl viewRootControl, DotvvmBindableControl targetControl, string validationTargetPath)
        {
            // walk the control tree and find the path
            ControlCommandBindingExpression resultBinding = null;
            DotvvmProperty resultProperty = null;
            DotvvmBindableControl resultControl = null;

            var walker = new ControlTreeWalker(viewRootControl);
            walker.ProcessControlTree((control) =>
            {
                // compare path
                if (control is DotvvmBindableControl && ViewModelPathComparer.AreEqual(path, walker.CurrentPathArray))
                {
                    // find bindings of current control
                    var bindableControl = (DotvvmBindableControl)control;
                    var binding = bindableControl.GetAllBindings().Where(p => p.Value is ControlCommandBindingExpression)
                        .FirstOrDefault(b => b.Value.BindingId == commandId);
                    if (binding.Key != null)
                    {
                        // verify that the target control is the control command target
                        if (bindableControl.GetClosestControlBindingTarget() == targetControl)
                        {
                            // we have found the binding, now get the validation path
                            var currentValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(bindableControl);
                            if (currentValidationTargetPath == validationTargetPath)
                            {
                                // the validation path is equal, we have found the binding
                                resultBinding = (ControlCommandBindingExpression)binding.Value;
                                resultProperty = binding.Key;
                                resultControl = bindableControl;
                            }
                        }
                    }
                }
            });

            return new FindBindingResult
            {
                Property = resultProperty,
                Binding = resultBinding,
                Control = resultControl
            };
        }