示例#1
0
        /// <summary>
        /// Finds the binding of the specified type on the specified viewmodel path.
        /// </summary>
        private FindBindingResult FindControlCommandBinding(string[] path, string commandId, DotvvmControl viewRootControl, DotvvmControl targetControl, string validationTargetPath)
        {
            // walk the control tree and find the path
            ControlCommandBindingExpression resultBinding = null;
            DotvvmProperty resultProperty = null;
            DotvvmControl  resultControl  = null;

            var walker = new ControlTreeWalker(viewRootControl);

            walker.ProcessControlTree((control) =>
            {
                // compare path
                if (ViewModelPathComparer.AreEqual(path, walker.CurrentPathArray))
                {
                    // find bindings of current control
                    var binding = control.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 (control.GetClosestControlBindingTarget() == targetControl)
                        {
                            // we have found the binding, now get the validation path
                            var currentValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(control);
                            if (currentValidationTargetPath == validationTargetPath)
                            {
                                // the validation path is equal, we have found the binding
                                resultBinding  = (ControlCommandBindingExpression)binding.Value;
                                resultProperty = binding.Key;
                                resultControl  = control;
                            }
                        }
                    }
                }
            });

            return(new FindBindingResult
            {
                Property = resultProperty,
                Binding = resultBinding,
                Control = resultControl
            });
        }
示例#2
0
        /// <summary>
        /// Finds the binding of the specified type on the specified viewmodel path.
        /// </summary>
        private FindBindingResult FindCommandBinding(string[] path, string commandId, DotvvmBindableObject viewRootControl, string validationTargetPath)
        {
            // walk the control tree and find the path
            CommandBindingExpression resultBinding  = null;
            DotvvmBindableObject     resultControl  = null;
            DotvvmProperty           resultProperty = null;

            var walker = new ControlTreeWalker(viewRootControl);

            walker.ProcessControlTree((control) =>
            {
                // compare path
                if (resultBinding == null && ViewModelPathComparer.AreEqual(path, walker.CurrentPathArray))
                {
                    // find bindings of current control
                    var binding = control.GetAllBindings()
                                  .FirstOrDefault(b => b.Value is CommandBindingExpression commandBinding && commandBinding.BindingId == commandId);
                    if (binding.Key != null)
                    {
                        // we have found the binding, now get the validation path
                        var currentValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(control);
                        if (currentValidationTargetPath == validationTargetPath)
                        {
                            // the validation path is equal, we have found the binding
                            resultBinding  = (CommandBindingExpression)binding.Value;
                            resultControl  = control;
                            resultProperty = binding.Key;
                        }
                    }
                }
            });

            return(new FindBindingResult
            {
                Binding = resultBinding,
                Control = resultControl,
                Property = resultProperty
            });
        }
示例#3
0
        public void Test()
        {
            var root = new StackPanel();
            var c1   = new StackPanel();
            var c2   = new StackPanel();
            var c11  = new StackPanel();
            var c12  = new StackPanel();
            var c21  = new StackPanel();
            var c22  = new StackPanel();

            root.Add(c1);
            root.Add(c2);
            c1.Add(c11);
            c1.Add(c12);
            c2.Add(c21);
            c2.Add(c22);

            List <Control> directOrder = new List <Control>();
            Control        c           = root;

            for (int i = 0; i < 8; i++, c = ControlTreeWalker.GetNextControl(c))
            {
                directOrder.Add(c);
            }

            Assert.That(directOrder.ToArray(), Is.EqualTo(new Control[] { root, c1, c11, c12, c2, c21, c22, root }));

            List <Control> reverseOrder = new List <Control>();

            c = root;
            for (int i = 0; i < 8; i++, c = ControlTreeWalker.GetPreviousControl(c))
            {
                reverseOrder.Add(c);
            }

            Assert.That(reverseOrder.ToArray(), Is.EqualTo(new Control[] { root, c22, c21, c2, c12, c11, c1, root }));
        }
示例#4
0
        /// <summary>
        /// Finds the binding of the specified type on the specified viewmodel path.
        /// </summary>
        /// <param name="path">DataContext path of the binding</param>
        /// <param name="commandId">Id of the binding</param>
        /// <param name="viewRootControl">ViewRootControl of the binding</param>
        /// <param name="targetControl">Target control of the binding, null if not finding control command binding</param>
        /// <param name="validationTargetPath">Validation path of the binding</param>
        /// <param name="findControl">Determinate whether finding control command binding or not</param>
        /// <returns></returns>
        private FindBindingResult FindCommandBinding(string[] path, string commandId,
                                                     DotvvmBindableObject viewRootControl, DotvvmBindableObject targetControl,
                                                     string validationTargetPath, bool findControl)
        {
            // walk the control tree and find the path
            CommandBindingExpression resultBinding  = null;
            DotvvmBindableObject     resultControl  = null;
            DotvvmProperty           resultProperty = null;

            bool   checkControl;
            bool   bindingInPath     = false;
            var    candidateBindings = new Dictionary <string, CandidateBindings>();
            string errorMessage      = null;

            var walker = new ControlTreeWalker(viewRootControl);

            walker.ProcessControlTree((control) =>
            {
                if (resultBinding == null)
                {
                    // find bindings of current control
                    var bindings = control.GetAllBindings()
                                   .Where(b => b.Value is CommandBindingExpression);

                    foreach (var binding in bindings)
                    {
                        var wrongExceptionPropertyKeys   = new List <string>();
                        var correctExceptionPropertyKeys = new List <string>();
                        var infoMessage = new StringBuilder();

                        // checking path
                        if (!ViewModelPathComparer.AreEqual(path, walker.CurrentPathArray))
                        {
                            wrongExceptionPropertyKeys.Add("DataContext path");
                            infoMessage.Append(
                                $"Expected DataContext path: '{string.Join("/", path)}' Command binding DataContext path: '{string.Join("/", walker.CurrentPathArray)}'");
                        }
                        else
                        {
                            //Found a binding in DataContext
                            bindingInPath = true;
                            correctExceptionPropertyKeys.Add("DataContext path");
                        }

                        //checking binding id
                        if (((CommandBindingExpression)binding.Value).BindingId != commandId)
                        {
                            wrongExceptionPropertyKeys.Add("binding id");
                        }
                        else
                        {
                            correctExceptionPropertyKeys.Add("binding id");
                        }

                        //checking validation path
                        var currentValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(control);
                        if (currentValidationTargetPath != validationTargetPath)
                        {
                            wrongExceptionPropertyKeys.Add("validation path");
                            infoMessage.Append($"Expected validation path: '{string.Join("/", validationTargetPath)}' Command binding validation path: '{string.Join("/", currentValidationTargetPath)}'");
                        }
                        else
                        {
                            correctExceptionPropertyKeys.Add("validation path");
                        }

                        //If finding control command binding checks if the binding is control otherwise always true
                        checkControl = !findControl || control.GetClosestControlBindingTarget() == targetControl;

                        if (!wrongExceptionPropertyKeys.Any() && checkControl)
                        {
                            //correct binding found
                            resultBinding  = (CommandBindingExpression)binding.Value;
                            resultControl  = control;
                            resultProperty = binding.Key;
                        }
                        else if (wrongExceptionPropertyKeys.Any())
                        {
                            var exceptionPropertyKey =
                                (findControl && checkControl
                                    ? "Control command bindings with wrong "
                                    : "Command bindings with wrong ") + string.Join(", ", wrongExceptionPropertyKeys)
                                + (correctExceptionPropertyKeys.Any()
                                    ? " and correct " + string.Join(", ", correctExceptionPropertyKeys)
                                    : "")
                                + ":";
                            if (!candidateBindings.ContainsKey(exceptionPropertyKey))
                            {
                                candidateBindings.Add(exceptionPropertyKey, new CandidateBindings());
                            }
                            candidateBindings[exceptionPropertyKey]
                            .AddBinding(new KeyValuePair <string, IBinding>(infoMessage.ToString(), binding.Value));
                        }
                        else
                        {
                            errorMessage = "Invalid command invocation (the binding is not control command binding)";
                        }
                    }
                }
            });

            return(new FindBindingResult
            {
                ErrorMessage = bindingInPath ? errorMessage : "Nothing was found in found inside specified DataContext check if ViewModel is populated",
                CandidateBindings = candidateBindings,
                Binding = resultBinding,
                Control = resultControl,
                Property = resultProperty
            });
        }