public DotvvmControlException(DotvvmBindableObject control, string message, Exception innerException = null) : base(message, innerException) { ControlType = control.GetType(); LineNumber = (int?)Internal.MarkupLineNumberProperty.GetValue(control); FileName = (string)Internal.MarkupFileNameProperty.GetValue(control); }
/// <summary> /// Evaluates the binding. /// </summary> public object Evaluate(DotvvmBindableObject control, DotvvmProperty property, params object[] args) { var action = GetCommandDelegate(control, property); if (action is Command) return (action as Command)(); if (action is Action) { (action as Action)(); return null; } return action.DynamicInvoke(args); }
protected virtual void SetValidatorValueBinding(DotvvmBindableObject textBox, BindingExpression valueBindingExpression) { if (CanValidate) { textBox.SetBinding(Validator.ValueProperty, valueBindingExpression); } }
/// <summary> /// Processes the control tree. /// </summary> private void ProcessControlTreeCore(DotvvmBindableObject control, Action <DotvvmBindableObject> action) { // if there is a DataContext binding, locate the correct token var hasDataContext = false; var pathValue = control.GetDataContextPathFragment(); if (pathValue != null) { CurrentPath.Push(pathValue as string); RefreshCurrentPathArray(); hasDataContext = true; } action(control); // go through all children foreach (var child in control.GetLogicalChildren()) { ProcessControlTreeCore(child, action); } if (hasDataContext) { CurrentPath.Pop(); RefreshCurrentPathArray(); } }
protected void ExecUpdateDelegate(DotvvmBindableObject contextControl, object value, bool seeThis, bool setRootControl = false) { var dataContexts = GetDataContexts(contextControl, seeThis); var control = setRootControl ? GetRootControl(contextControl) : null; UpdateDelegate(dataContexts, control, value); }
public DotvvmControlException(DotvvmBindableObject control, string message, Exception innerException = null) : base(message, innerException) { ControlType = control.GetType(); LineNumber = (int?)Internal.MarkupLineNumberProperty.GetValue(control); if (control.Parent != null) control = control.Parent; FileName = (string)Internal.MarkupFileNameProperty.GetValue(control); }
private object ResolveStaticCommandService(DotvvmBindableObject c, Type type) { var context = (IDotvvmRequestContext)c.GetValue(Internal.RequestContextProperty, true); #pragma warning disable CS0618 return(context.Services.GetRequiredService <IStaticCommandServiceLoader>().GetStaticCommandService(type, context)); #pragma warning restore CS0618 }
public override object?GetValue(DotvvmBindableObject control, bool inherit = true) { if (!TryGetValue(control, out var value, inherit)) { return(FallbackProperty.GetValue(control, inherit)); } return(value); }
public static DataContextStack CreateChildStack(this DotvvmBindableObject bindableObject, Type viewModelType) { var dataContextTypeStack = bindableObject.GetDataContextType(); return(DataContextStack.Create( viewModelType, dataContextTypeStack, dataContextTypeStack.NamespaceImports, dataContextTypeStack.ExtensionParameters, dataContextTypeStack.BindingPropertyResolvers)); }
/// <summary> /// Gets all data context on the path to root /// </summary> public static object[] GetDataContexts(DotvvmBindableObject contextControl, bool seeThis) { var context = seeThis ? contextControl.GetValue(DotvvmBindableObject.DataContextProperty, false) : null; return ((context == null ? new object[0] : new[] { context }) .Concat(contextControl.GetAllAncestors().OfType <DotvvmBindableObject>() .Where(c => c.properties.ContainsKey(DotvvmBindableObject.DataContextProperty)) .Select(c => c.GetValue(DotvvmBindableObject.DataContextProperty, false))) .ToArray()); }
public virtual object?GetValue(DotvvmBindableObject control, bool inherit = true) { if (control.properties.TryGet(this, out var value)) { return(value); } if (IsValueInherited && inherit && control.Parent != null) { return(GetValue(control.Parent)); } return(DefaultValue); }
public static void CopyProperty(DotvvmBindableObject source, DotvvmProperty sourceProperty, DotvvmBindableObject target, DotvvmProperty targetProperty) { var binding = source.GetValueBinding(sourceProperty); if (binding != null) { target.SetBinding(targetProperty, binding); } else { target.SetValue(targetProperty, source.GetValue(sourceProperty)); } }
protected object ExecDelegate(DotvvmBindableObject 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; } }
protected object ExecDelegate(DotvvmBindableObject contextControl, bool seeThis) { var dataContexts = GetDataContexts(contextControl, seeThis); var control = GetRootControl(contextControl); try { return(Delegate(dataContexts, control)); } catch (NullReferenceException) { return(null); } }
/// <summary> /// Evaluates the binding. /// </summary> public object Evaluate(DotvvmBindableObject control, DotvvmProperty property, params object[] args) { var action = GetCommandDelegate(control, property); if (action is Command) { return((action as Command)()); } if (action is Action) { (action as Action)(); return(null); } return(action.DynamicInvoke(args)); }
public virtual bool IsSet(DotvvmBindableObject control, bool inherit = true) { if (control.properties.Contains(this)) { return(true); } if (IsValueInherited && inherit && control.Parent != null) { return(IsSet(control.Parent)); } return(false); }
/// <summary> /// Gets whether the value of the property is set /// </summary> public override bool IsSet(DotvvmBindableObject control, bool inherit = true) { if (control.properties != null && control.properties.ContainsKey(this)) { return(true); } if (IsValueInherited && inherit && control.Parent != null) { return(IsSet(control.Parent)); } return(DefaultProperty.IsSet(control, DefaultPropertyInherit)); }
private bool TryGetValue(DotvvmBindableObject control, out object?value, bool inherit = true) { if (control.properties.TryGet(this, out value)) { return(true); } if (IsValueInherited && inherit && control.Parent != null) { return(TryGetValue(control.Parent, out value)); } value = null; return(false); }
public static void AndAssignProperty(this DotvvmBindableObject obj, DotvvmProperty property, object value) { if (property.PropertyType != typeof(bool)) { throw new NotSupportedException($"Can only AND boolean properties, {property} is of type {property.PropertyType}"); } if (!obj.IsPropertySet(property)) { obj.SetValue(property, value); } else { if (value is bool b && !b) { obj.SetValue(property, false); }
/// <summary> /// Gets all data context on the path to root /// </summary> public static object[] GetDataContexts(DotvvmBindableObject contextControl, bool seeThis) { if (!seeThis) { contextControl = contextControl.Parent; if (contextControl == null) { return new object[0]; } } // PERF: return new [] { contextControl }.Concat(contextControl.GetAllAncestors()) .Where(c => c.IsPropertySet(DotvvmBindableObject.DataContextProperty, false)) .Select(c => c.GetValue(DotvvmBindableObject.DataContextProperty, false)) .ToArray(); }
private static string TranslateRouteParameter(DotvvmBindableObject control, KeyValuePair <string, object> param, bool caseSensitive = false) { string expression = ""; if (param.Value is IBinding) { EnsureValidBindingType(param.Value as IBinding); expression = (param.Value as IValueBinding)?.GetKnockoutBindingExpression(control) ?? JsonConvert.SerializeObject((param.Value as IStaticValueBinding)?.Evaluate(control), DefaultViewModelSerializer.CreateDefaultSettings()); } else { expression = JsonConvert.SerializeObject(param.Value, DefaultViewModelSerializer.CreateDefaultSettings()); } return(JsonConvert.SerializeObject(caseSensitive ? param.Key : param.Key.ToLower()) + ": " + expression); }
/// <summary> /// Gets all data context on the path to root /// </summary> public static object[] GetDataContexts(DotvvmBindableObject contextControl, bool seeThis) { if (!seeThis) { contextControl = contextControl.Parent; if (contextControl == null) { return(new object[0]); } } // PERF: return(new [] { contextControl }.Concat(contextControl.GetAllAncestors()) .Where(c => c.IsPropertySet(DotvvmBindableObject.DataContextProperty, false)) .Select(c => c.GetValue(DotvvmBindableObject.DataContextProperty, false)) .ToArray()); }
/// <summary> /// Gets the value of the property. /// </summary> public override object GetValue(DotvvmBindableObject control, bool inherit = true) { object value; if (control.properties != null) { if (control.properties.TryGetValue(this, out value)) { return(value); } } if (IsValueInherited && inherit && control.Parent != null) { return(GetValue(control.Parent)); } return(DefaultProperty.GetValue(control, DefaultPropertyInherit)); }
/// <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 }); }
/// <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().Where(p => p.Value is CommandBindingExpression) .FirstOrDefault(b => b.Value.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 }; }
/// <summary> /// Processes the control tree. /// </summary> private void ProcessControlTreeCore(DotvvmBindableObject control, Action<DotvvmBindableObject> action) { // if there is a DataContext binding, locate the correct token var hasDataContext = false; var pathValue = control.GetValue(Internal.PathFragmentProperty, false); if (pathValue != null) { CurrentPath.Push(pathValue as string); RefreshCurrentPathArray(); hasDataContext = true; } else { var binding = control.GetValueBinding(DotvvmBindableObject.DataContextProperty, false); if (binding != null) { CurrentPath.Push(binding.GetKnockoutBindingExpression()); RefreshCurrentPathArray(); hasDataContext = true; } } action(control); // go through all children foreach (var child in control.GetLogicalChildren()) { ProcessControlTreeCore(child, action); } if (hasDataContext) { CurrentPath.Pop(); RefreshCurrentPathArray(); } }
public override object Evaluate(DotvvmBindableObject control, DotvvmProperty property) { return ExecDelegate(control, property != DotvvmBindableObject.DataContextProperty, setRootControl: true); }
/// <summary> /// Gets Internal.PathFragmentProperty or DataContext.KnockoutExpression /// </summary> public static string GetDataContextPathFragment(this DotvvmBindableObject currentControl) => (string)currentControl.GetValue(Internal.PathFragmentProperty, inherit: false) ??
/// <summary> /// Gets the validation target expression. /// </summary> public static string GetValidationTargetExpression(DotvvmBindableObject control) { if (!(bool)control.GetValue(Validation.EnabledProperty)) { return null; } // find the closest control int dataSourceChanges; var validationTargetControl = control.GetClosestWithPropertyValue(out dataSourceChanges, c => c.GetValueBinding(Validation.TargetProperty) != null); if (validationTargetControl == null) { return "$root"; } // reparent the expression to work in current DataContext // FIXME: This does not work: var validationBindingExpression = validationTargetControl.GetValueBinding(Validation.TargetProperty); string validationExpression = validationBindingExpression.GetKnockoutBindingExpression(); validationExpression = string.Join("", Enumerable.Range(0, dataSourceChanges).Select(i => "$parent.")) + validationExpression; return validationExpression; }
/// <summary> /// Called right before the page is rendered. /// </summary> public void OnControlRendering(DotvvmBindableObject dotvvmControl) { }
public override Delegate GetCommandDelegate(DotvvmBindableObject control, DotvvmProperty property) { return (Delegate)ExecDelegate(control, true, true); }
public static ParametrizedCode GetParametrizedKnockoutExpression(this IValueBinding binding, DotvvmBindableObject currentControl, bool unwrapped = false) => JavascriptTranslator.AdjustKnockoutScriptContext(unwrapped ? binding.UnwrappedKnockoutExpression : binding.KnockoutExpression, dataContextLevel: FindDataContextTarget(binding, currentControl).stepsUp);
/// <summary> /// Initializes a new instance of the <see cref="ControlTreeWalker"/> class. /// </summary> public ControlTreeWalker(DotvvmBindableObject root) { this.root = root; }
private DotvvmBindableObject GetRootControl(DotvvmBindableObject control) { return control.GetClosestControlBindingTarget(); }
public static string?GetDataContextPathFragment(this DotvvmBindableObject currentControl) => (string?)currentControl.GetValue(Internal.PathFragmentProperty, inherit: false) ?? (currentControl.GetBinding(DotvvmBindableObject.DataContextProperty, inherit: false) is IValueBinding binding ?
public virtual Delegate GetCommandDelegate(DotvvmBindableObject control, DotvvmProperty property) { return (Delegate)ExecDelegate(control, property != DotvvmBindableObject.DataContextProperty); }
public override Delegate GetCommandDelegate(DotvvmBindableObject control, DotvvmProperty property) { throw new NotImplementedException(); }
public virtual void SetValue(DotvvmBindableObject control, object?value) { control.properties.Set(this, value); }
/// <summary> /// Sets the value of the property. /// </summary> public virtual void SetValue(DotvvmBindableObject control, object value) { control.Properties[this] = value; }
public static string GetKnockoutBindingExpression(this IValueBinding binding, DotvvmBindableObject currentControl, bool unwrapped = false) => (unwrapped ? binding.UnwrappedKnockoutExpression : binding.KnockoutExpression) .FormatKnockoutScript(currentControl, binding);
/// <summary> /// Called when a control of the property type is created and initialized. /// </summary> protected internal virtual void OnControlInitialized(DotvvmBindableObject dotvvmControl) { }
public static string FormatKnockoutScript(this ParametrizedCode code, DotvvmBindableObject currentControl, IBinding currentBinding) => JavascriptTranslator.FormatKnockoutScript(code, dataContextLevel: FindDataContextTarget(currentBinding, currentControl).stepsUp);
/// <summary> /// Updates the viewModel with the new value. /// </summary> public virtual void UpdateSource(object value, DotvvmBindableObject control, DotvvmProperty property) { ExecUpdateDelegate(control, value, property != DotvvmBindableObject.DataContextProperty); }
private object ResolveStaticCommandService(DotvvmBindableObject c, Type type) { var context = (IDotvvmRequestContext)c.GetValue(Internal.RequestContextProperty, true); return(context.Services.GetService <IStaticCommandServiceLoader>().GetStaticCommandService(type, context)); }
/// <summary> /// Evaluates the binding. /// </summary> public virtual object Evaluate(DotvvmBindableObject control, DotvvmProperty property) { return ExecDelegate(control, property != DotvvmBindableObject.DataContextProperty); }