public virtual void CreateHeaderControls(IDotvvmRequestContext context, GridView gridView, Action <string> sortCommand, HtmlGenericControl cell, IGridViewDataSet gridViewDataSet) { if (HeaderTemplate != null) { HeaderTemplate.BuildContent(context, cell); return; } if (AllowSorting) { if (sortCommand == null) { throw new DotvvmControlException(this, "Cannot use column sorting where no sort command is specified. Either put IGridViewDataSet in the DataSource property of the GridView, or set the SortChanged command on the GridView to implement custom sorting logic!"); } var sortExpression = GetSortExpression(); var linkButton = new LinkButton(); linkButton.SetValue(LinkButton.TextProperty, GetValueRaw(HeaderTextProperty)); cell.Children.Add(linkButton); var bindingId = linkButton.GetValue(Internal.UniqueIDProperty) + "_sortBinding"; var binding = new CommandBindingExpression(context.Services.GetRequiredService <BindingCompilationService>().WithoutInitialization(), h => sortCommand(sortExpression), bindingId); linkButton.SetBinding(ButtonBase.ClickProperty, binding); SetSortedCssClass(cell, gridViewDataSet); } else { var literal = new Literal(); literal.SetValue(Literal.TextProperty, GetValueRaw(HeaderTextProperty)); cell.Children.Add(literal); } }
public void CommandResolver_Valid_SimpleTest() { var path = new[] { new ValueBindingExpression(vm => ((dynamic)vm[0]).A[0], "A()[0]") }; var commandId = "someCommand"; var command = new CommandBindingExpression(vm => ((TestA)vm[0]).Test(((TestA)vm[0]).StringToPass, ((dynamic)vm[1]).NumberToPass), commandId); var testObject = new { A = new[] { new TestA() { StringToPass = "******" } }, NumberToPass = 16 }; var viewRoot = new DotvvmView() { DataContext = testObject }; viewRoot.SetBinding(Controls.Validation.TargetProperty, new ValueBindingExpression(vm => vm.Last(), "$root")); var placeholder = new HtmlGenericControl("div"); placeholder.SetBinding(DotvvmBindableObject.DataContextProperty, path[0]); viewRoot.Children.Add(placeholder); var button = new Button(); button.SetBinding(ButtonBase.ClickProperty, command); placeholder.Children.Add(button); var resolver = new CommandResolver(); var context = new DotvvmRequestContext() { ViewModel = testObject }; context.ModelState.ValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(button); resolver.GetFunction(viewRoot, context, path.Select(v => v.Javascript).ToArray(), commandId).Action(); Assert.AreEqual(testObject.NumberToPass, testObject.A[0].ResultInt); Assert.AreEqual(testObject.A[0].ResultString, testObject.A[0].ResultString); }
public CommonBindings(BindingCompilationService service) { GoToNextPageCommand = new CommandBindingExpression(service, h => ((IPageableGridViewDataSet)h[0]).GoToNextPage(), "__$DataPager_GoToNextPage"); GoToThisPageCommand = new CommandBindingExpression(service, h => ((IPageableGridViewDataSet)h[1]).GoToPage((int)h[0]), "__$DataPager_GoToThisPage"); GoToPrevPageCommand = new CommandBindingExpression(service, h => ((IPageableGridViewDataSet)h[0]).GoToPreviousPage(), "__$DataPager_GoToPrevPage"); GoToFirstPageCommand = new CommandBindingExpression(service, h => ((IPageableGridViewDataSet)h[0]).GoToFirstPage(), "__$DataPager_GoToFirstPage"); GoToLastPageCommand = new CommandBindingExpression(service, h => ((IPageableGridViewDataSet)h[0]).GoToLastPage(), "__$DataPager_GoToLastPage"); }
public static CommandBindingExpression RegisterExtensionCommand(this DotvvmControl control, Delegate action, string methodUsageId) { var id = control.GetDotvvmUniqueId() + methodUsageId; var propertyName = control.GetType().FullName + "/" + methodUsageId; var property = DotvvmProperty.Register<object, ExtensionCommands>(propertyName); var binding = new CommandBindingExpression(action, id); control.SetBinding(property, binding); return binding; }
public void CommandResolver_Valid_SimpleTest() { var path = new[] { ValueBindingExpression.CreateBinding <object>(bindingService, vm => ((Test1)vm[0]).A[0], (DataContextStack)null) }; var commandId = "someCommand"; var command = new CommandBindingExpression(bindingService, vm => { ((TestA)vm[0]).Test(((TestA)vm[0]).StringToPass, ((dynamic)vm[1]).NumberToPass); }, commandId); var testObject = new Test1 { A = new[] { new TestA() { StringToPass = "******" } }, NumberToPass = 16 }; var viewRoot = new DotvvmView() { DataContext = testObject }; viewRoot.SetBinding(Controls.Validation.TargetProperty, ValueBindingExpression.CreateBinding(bindingService, vm => vm.Last(), new ParametrizedCode("$root"))); var placeholder = new HtmlGenericControl("div"); placeholder.SetBinding(DotvvmBindableObject.DataContextProperty, path[0]); viewRoot.Children.Add(placeholder); var button = new Button(); button.SetBinding(ButtonBase.ClickProperty, command); placeholder.Children.Add(button); var resolver = new CommandResolver(); var context = new TestDotvvmRequestContext() { ViewModel = testObject, ModelState = new ModelState() }; context.ModelState.ValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(button); resolver.GetFunction(viewRoot, context, path.Select(v => v.GetProperty <SimplePathExpressionBindingProperty>().Code.FormatKnockoutScript(button, v)).ToArray(), commandId, new Func <Type, object> [0]).Action(); Assert.AreEqual(testObject.NumberToPass, testObject.A[0].ResultInt); Assert.AreEqual(testObject.A[0].ResultString, testObject.A[0].ResultString); }
public void CommandResolver_Valid_SimpleTest() { var path = new[] { new ValueBindingExpression(vm => ((dynamic)vm[0]).A[0], "A()[0]") }; var commandId = "someCommand"; var command = new CommandBindingExpression(vm => ((TestA)vm[0]).Test(((TestA)vm[0]).StringToPass, ((dynamic)vm[1]).NumberToPass), commandId); var testObject = new { A = new[] { new TestA() { StringToPass = "******" } }, NumberToPass = 16 }; var viewRoot = new DotvvmView() { DataContext = testObject }; viewRoot.SetBinding(Validate.TargetProperty, new ValueBindingExpression(vm => vm.Last(), "$root")); var placeholder = new HtmlGenericControl("div"); placeholder.SetBinding(DotvvmBindableObject.DataContextProperty, path[0]); viewRoot.Children.Add(placeholder); var button = new Button(); button.SetBinding(ButtonBase.ClickProperty, command); placeholder.Children.Add(button); var resolver = new CommandResolver(); var context = new DotvvmRequestContext() { ViewModel = testObject }; context.ModelState.ValidationTargetPath = KnockoutHelper.GetValidationTargetExpression(button); resolver.GetFunction(viewRoot, context, path.Select(v => v.Javascript).ToArray(), commandId).Action(); Assert.AreEqual(testObject.NumberToPass, testObject.A[0].ResultInt); Assert.AreEqual(testObject.A[0].ResultString, testObject.A[0].ResultString); }
/// <summary> /// Finds the binding of the specified type on the specified viewmodel path. /// </summary> private FindBindingResult FindControlCommandBinding(string[] path, string commandId, DotvvmControl viewRootControl, DotvvmBindableObject targetControl, string validationTargetPath) { // walk the control tree and find the path CommandBindingExpression resultBinding = null; DotvvmProperty resultProperty = null; DotvvmBindableObject 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 CommandBindingExpression) .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 = (CommandBindingExpression)binding.Value; resultProperty = binding.Key; resultControl = control; } } } } }); return(new FindBindingResult { Property = resultProperty, Binding = resultBinding, Control = resultControl }); }
public virtual void CreateHeaderControls(IDotvvmRequestContext context, GridView gridView, Action <string> sortCommand, HtmlGenericControl cell) { if (AllowSorting) { if (sortCommand == null) { throw new DotvvmControlException(this, "Cannot use column sorting where no sort command is specified. Either put IGridViewDataSet in the DataSource property of the GridView, or set the SortChanged command on the GridView to implement custom sorting logic!"); } var sortExpression = GetSortExpression(); var linkButton = new LinkButton(); if (HeaderTemplate != null) { HeaderTemplate.BuildContent(context, linkButton); } else { linkButton.Text = HeaderText; } cell.Children.Add(linkButton); var bindingId = linkButton.GetValue(Internal.UniqueIDProperty) + "_sortBinding"; var binding = new CommandBindingExpression(h => sortCommand(sortExpression), bindingId); linkButton.SetBinding(ButtonBase.ClickProperty, binding); } else { if (HeaderTemplate == null) { var literal = new Literal(HeaderText); cell.Children.Add(literal); } else { HeaderTemplate.BuildContent(context, cell); } } }
public virtual void CreateHeaderControls(IDotvvmRequestContext context, GridView gridView, Action<string> sortCommand, HtmlGenericControl cell, IGridViewDataSet gridViewDataSet) { if (HeaderTemplate != null) { HeaderTemplate.BuildContent(context, cell); return; } if (AllowSorting) { if (sortCommand == null) { throw new DotvvmControlException(this, "Cannot use column sorting where no sort command is specified. Either put IGridViewDataSet in the DataSource property of the GridView, or set the SortChanged command on the GridView to implement custom sorting logic!"); } var sortExpression = GetSortExpression(); var linkButton = new LinkButton(); linkButton.SetValue(LinkButton.TextProperty, GetValueRaw(HeaderTextProperty)); cell.Children.Add(linkButton); var bindingId = linkButton.GetValue(Internal.UniqueIDProperty) + "_sortBinding"; var binding = new CommandBindingExpression(h => sortCommand(sortExpression), bindingId); linkButton.SetBinding(ButtonBase.ClickProperty, binding); SetSortedCssClass(cell, gridViewDataSet); } else { var literal = new Literal(); literal.SetValue(Literal.TextProperty, GetValueRaw(HeaderTextProperty)); cell.Children.Add(literal); } }
/// <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 }); }