/// <summary>
        /// Gets the data context change behavior for the specified control property.
        /// </summary>
        protected virtual IDataContextStack GetDataContextChange(IDataContextStack dataContext, IAbstractControl control, IPropertyDescriptor property)
        {
            if (dataContext == null)
            {
                return(null);
            }

            var manipulationAttribute = property != null ? property.DataContextManipulationAttribute : control.Metadata.DataContextManipulationAttribute;

            if (manipulationAttribute != null)
            {
                return(manipulationAttribute.ChangeStackForChildren(dataContext, control, property, (parent, changeType) => CreateDataContextTypeStack(changeType, parentDataContextStack: parent)));
            }

            var attributes = property != null ? property.DataContextChangeAttributes : control.Metadata.DataContextChangeAttributes;

            if (attributes == null || attributes.Length == 0)
            {
                return(dataContext);
            }

            var type = dataContext.DataContextType;

            foreach (var attribute in attributes.OrderBy(a => a.Order))
            {
                type = attribute.GetChildDataContextType(type, dataContext, control, property);
                if (type == null)
                {
                    break;
                }
            }
            return(CreateDataContextTypeStack(type, parentDataContextStack: dataContext));
        }
示例#2
0
 public IAbstractBinding BuildBinding(BindingParserOptions bindingOptions, IDataContextStack dataContext, DothtmlBindingNode node, IPropertyDescriptor property)
 {
     return(new ResolvedBinding(bindingService, bindingOptions, (DataContextStack)dataContext, node.Value, property: property as DotvvmProperty)
     {
         DothtmlNode = node,
     });
 }
 protected override IDataContextStack CreateDataContextTypeStack(ITypeDescriptor viewModelType, ITypeDescriptor wrapperType = null, IDataContextStack parentDataContextStack = null)
 {
     var dataContextTypeStack = new DataContextStack(ResolvedTypeDescriptor.ToSystemType(viewModelType), parentDataContextStack as DataContextStack);
     if (wrapperType != null)
     {
         dataContextTypeStack.RootControlType = ResolvedTypeDescriptor.ToSystemType(wrapperType);
     }
     return dataContextTypeStack;
 }
示例#4
0
        private IAbstractControl ProcessHtmlComment(DothtmlNode node, IDataContextStack dataContext, DotHtmlCommentNode commentNode)
        {
            var text = commentNode.IsServerSide ? "" : "<!--" + commentNode.Value + "-->";

            var literal = treeBuilder.BuildControl(rawLiteralMetadata.Value, node, dataContext);

            literal.ConstructorParameters = new object[] { text, commentNode.Value, true };
            return(literal);
        }
示例#5
0
 public IAbstractBinding BuildBinding(BindingParserOptions bindingOptions, IDataContextStack dataContext, DothtmlBindingNode node, ITypeDescriptor resultType = null, Exception parsingError = null, object customData = null)
 {
     return(new ResolvedBinding()
     {
         BindingType = bindingOptions.BindingType,
         Value = node.Value,
         Expression = (Expression)customData,
         DataContextTypeStack = (DataContextStack)dataContext,
         ParsingError = parsingError,
         DothtmlNode = node,
         ResultType = resultType
     });
 }
示例#6
0
 public IAbstractBinding BuildBinding(BindingParserOptions bindingOptions, DothtmlBindingNode node, IDataContextStack dataContext, Exception parsingError, ITypeDescriptor resultType, object customData)
 {
     return new ResolvedBinding()
     {
         BindingType = bindingOptions.BindingType,
         Value = node.Value,
         Expression = (Expression)customData,
         DataContextTypeStack = (DataContextStack)dataContext,
         ParsingError = parsingError,
         BindingNode = node,
         ResultType = resultType
     };
 }
示例#7
0
 public override IDataContextStack ChangeStackForChildren(IDataContextStack original, IAbstractControl control, IPropertyDescriptor property, Func <IDataContextStack, ITypeDescriptor, IDataContextStack> createNewFrame)
 {
     return(DataContextStack.Create(ResolvedTypeDescriptor.ToSystemType(original.DataContextType), (DataContextStack)original.Parent,
                                    bindingPropertyResolvers: new Delegate[] {
         new Func <ParsedExpressionBindingProperty, ParsedExpressionBindingProperty>(e => {
             if (e.Expression.NodeType == ExpressionType.Constant && (string)((ConstantExpression)e.Expression).Value == "abc")
             {
                 return new ParsedExpressionBindingProperty(Expression.Constant("def"));
             }
             else
             {
                 return e;
             }
         })
     }));
 }
        private IAbstractControl ProcessBindingInText(DothtmlNode node, IDataContextStack dataContext)
        {
            var bindingNode = (DothtmlBindingNode)node;
            var literal     = treeBuilder.BuildControl(literalMetadata.Value, node, dataContext);

            var textBinding  = ProcessBinding(bindingNode, dataContext);
            var textProperty = treeBuilder.BuildPropertyBinding(Literal.TextProperty, textBinding, null);

            treeBuilder.SetProperty(literal, textProperty);

            var renderSpanElement = treeBuilder.BuildPropertyValue(Literal.RenderSpanElementProperty, false, null);

            treeBuilder.SetProperty(literal, renderSpanElement);

            return(literal);
        }
示例#9
0
        /// <summary>
        /// Processes the binding node.
        /// </summary>
        public IAbstractBinding ProcessBinding(DothtmlBindingNode node, IDataContextStack context, IPropertyDescriptor property)
        {
            var bindingOptions = controlResolver.ResolveBinding(node.Name);

            if (bindingOptions == null)
            {
                node.NameNode.AddError($"Binding {node.Name} could not be resolved.");
                bindingOptions = controlResolver.ResolveBinding("value"); // just try it as with value binding
            }

            if (context != null && context.NamespaceImports.Count > 0)
            {
                bindingOptions = bindingOptions.AddImports(context.NamespaceImports);
            }

            return(CompileBinding(node, bindingOptions, context, property));
        }
示例#10
0
        /// <summary>
        /// Gets the data context change behavior for the specified control property.
        /// </summary>
        protected virtual IDataContextStack GetDataContextChange(IDataContextStack dataContext, IAbstractControl control, IPropertyDescriptor property)
        {
            if (dataContext == null)
            {
                return(null);
            }

            var manipulationAttribute = property != null ? property.DataContextManipulationAttribute : control.Metadata.DataContextManipulationAttribute;

            if (manipulationAttribute != null)
            {
                return(manipulationAttribute.ChangeStackForChildren(dataContext, control, property, (parent, changeType) => CreateDataContextTypeStack(changeType, parentDataContextStack: parent)));
            }

            var attributes = property != null ? property.DataContextChangeAttributes : control.Metadata.DataContextChangeAttributes;

            if (attributes == null || attributes.Length == 0)
            {
                return(dataContext);
            }

            try
            {
                var(type, extensionParameters) = ApplyContextChange(dataContext, attributes, control, property);

                if (type == null)
                {
                    return(dataContext);
                }
                else
                {
                    return(CreateDataContextTypeStack(type, parentDataContextStack: dataContext, extensionParameters: extensionParameters.ToArray()));
                }
            }
            catch (Exception exception)
            {
                var node = property != null && control.TryGetProperty(property, out var v) ? v.DothtmlNode : control.DothtmlNode;
                node?.AddError($"Could not compute the type of DataContext: {exception}");

                return(CreateDataContextTypeStack(null, parentDataContextStack: dataContext));
            }
        }
        protected override IAbstractBinding CompileBinding(DothtmlBindingNode node, BindingParserOptions bindingOptions, IDataContextStack context)
        {
            Expression expression = null;
            Exception parsingError = null;
            ITypeDescriptor resultType = null;

            if (context == null)
            {
                parsingError = new DotvvmCompilationException("The DataContext couldn't be evaluated because of the errors above.", node.Tokens);
            }
            else
            {
                try
                {
                    expression = bindingExpressionBuilder.Parse(node.Value, (DataContextStack)context, bindingOptions);
                    resultType = new ResolvedTypeDescriptor(expression.Type);
                }
                catch (Exception exception)
                {
                    parsingError = exception;
                }
            }
            return treeBuilder.BuildBinding(bindingOptions, node, context, parsingError, resultType, expression);
        }
        public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
        {
            IPropertyDescriptor controlProperty;
            if (!control.Metadata.TryGetProperty(PropertyName, out controlProperty))
            {
                throw new Exception($"The property '{PropertyName}' was not found on control '{control.Metadata.Type}'!");
            }

            IAbstractPropertySetter setter;
            if (control.TryGetProperty(controlProperty, out setter))
            {
                var binding = setter as IAbstractPropertyBinding;
                if (binding == null)
                {
                    return dataContext;
                }
                return binding.Binding.ResultType;
            }
            else
            {
                if (AllowMissingProperty) return dataContext;
                else throw new Exception($"Property '{PropertyName}' is required on '{control.Metadata.Type.Name}'.");
            }
        }
示例#13
0
        /// <summary>
        /// Gets the data context change behavior for the specified control property.
        /// </summary>
        protected virtual IDataContextStack GetDataContextChange(IDataContextStack dataContext, IAbstractControl control, IPropertyDescriptor property)
        {
            if (dataContext == null)
            {
                return(null);
            }

            var manipulationAttribute = property != null ? property.DataContextManipulationAttribute : control.Metadata.DataContextManipulationAttribute;

            if (manipulationAttribute != null)
            {
                return(manipulationAttribute.ChangeStackForChildren(dataContext, control, property, (parent, changeType) => CreateDataContextTypeStack(changeType, parentDataContextStack: parent)));
            }

            var attributes = property != null ? property.DataContextChangeAttributes : control.Metadata.DataContextChangeAttributes;

            if (attributes == null || attributes.Length == 0)
            {
                return(dataContext);
            }

            var(type, extensionParameters) = ApplyContextChange(dataContext, attributes, control, property);
            return(CreateDataContextTypeStack(type, parentDataContextStack: dataContext, extensionParameters: extensionParameters.ToArray()));
        }
示例#14
0
 /// <summary>
 /// Processes the parser node and builds a control.
 /// </summary>
 public IAbstractControl ProcessNode(IAbstractTreeNode parent, DothtmlNode node, IControlResolverMetadata parentMetadata, IDataContextStack dataContext)
 {
     try
     {
         if (node is DothtmlBindingNode)
         {
             // binding in text
             EnsureContentAllowed(parentMetadata, node);
             return(ProcessBindingInText(node, dataContext));
         }
         else if (node is DotHtmlCommentNode)
         {
             // HTML comment
             var commentNode = node as DotHtmlCommentNode;
             return(ProcessHtmlComment(node, dataContext, commentNode));
         }
         else if (node is DothtmlLiteralNode)
         {
             // text content
             var literalNode = (DothtmlLiteralNode)node;
             return(ProcessText(node, parentMetadata, dataContext, literalNode));
         }
         else if (node is DothtmlElementNode)
         {
             // HTML element
             EnsureContentAllowed(parentMetadata, node);
             var element = (DothtmlElementNode)node;
             return(ProcessObjectElement(element, dataContext));
         }
         else
         {
             throw new NotSupportedException($"The node of type '{node.GetType()}' is not supported!");
         }
     }
     catch (DotvvmCompilationException ex)
     {
         if (ex.Tokens == null)
         {
             ex.Tokens       = node.Tokens;
             ex.ColumnNumber = node.Tokens.First().ColumnNumber;
             ex.LineNumber   = node.Tokens.First().LineNumber;
         }
         if (!LogError(ex, node))
         {
             throw;
         }
         else
         {
             return(null);
         }
     }
     catch (Exception ex)
     {
         if (!LogError(ex, node))
         {
             throw new DotvvmCompilationException("", ex, node.Tokens);
         }
         else
         {
             return(null);
         }
     }
 }
        public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
        {
            if (!control.Metadata.TryGetProperty(PropertyName, out var controlProperty))
            {
                throw new Exception($"The property '{PropertyName}' was not found on control '{control.Metadata.Type}'!");
            }

            if (control.TryGetProperty(controlProperty, out var setter) && setter is IAbstractPropertyBinding binding)
            {
                return(binding.Binding.ResultType);
            }

            return(controlProperty.PropertyType);
        }
示例#16
0
 public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
 {
     return(TypeDescriptorUtils.GetCollectionItemType(dataContext));
 }
 public override IDataContextStack ChangeStackForChildren(IDataContextStack original, IAbstractControl control, IPropertyDescriptor property, Func <IDataContextStack, ITypeDescriptor, IDataContextStack> createNewFrame)
 {
     return(original.Parent);
 }
 public abstract ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null);
示例#19
0
        public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
        {
            if (!control.Metadata.TryGetProperty(PropertyName, out var controlProperty))
            {
                throw new Exception($"The property '{PropertyName}' was not found on control '{control.Metadata.Type}'!");
            }

            if (control.TryGetProperty(controlProperty, out var setter))
            {
                return(setter is IAbstractPropertyBinding binding
                    ? binding.Binding.ResultType
                    : dataContext);
            }

            if (AllowMissingProperty)
            {
                return(dataContext);
            }

            throw new Exception($"Property '{PropertyName}' is required on '{control.Metadata.Type.Name}'.");
        }
示例#20
0
        /// <summary>
        /// Processes the HTML element that represents a new object.
        /// </summary>
        private IAbstractControl ProcessObjectElement(DothtmlElementNode element, IDataContextStack dataContext)
        {
            // build control
            var controlMetadata = controlResolver.ResolveControl(element.TagPrefix, element.TagName, out var constructorParameters);

            if (controlMetadata == null)
            {
                controlMetadata       = controlResolver.ResolveControl("", element.TagName, out constructorParameters);
                constructorParameters = new[] { element.FullTagName };
                element.AddError($"The control <{element.FullTagName}> could not be resolved! Make sure that the tagPrefix is registered in DotvvmConfiguration.Markup.Controls collection!");
            }
            var control = treeBuilder.BuildControl(controlMetadata, element, dataContext);

            control.ConstructorParameters = constructorParameters;

            // resolve data context
            var dataContextAttribute = element.Attributes.FirstOrDefault(a => a.AttributeName == "DataContext");

            if (dataContextAttribute != null)
            {
                ProcessAttribute(dataContextAttribute, control, dataContext);
            }

            IAbstractPropertySetter dataContextProperty;

            if (control.TryGetProperty(DotvvmBindableObject.DataContextProperty, out dataContextProperty) && dataContextProperty is IAbstractPropertyBinding)
            {
                var dataContextBinding = ((IAbstractPropertyBinding)dataContextProperty).Binding;
                if (dataContextBinding?.ResultType != null && dataContext != null)
                {
                    dataContext = CreateDataContextTypeStack(dataContextBinding?.ResultType, parentDataContextStack: dataContext);
                }
                else if (dataContext != null)
                {
                    dataContext = CreateDataContextTypeStack(null, dataContext);
                }
                else
                {
                    dataContext = null;
                }
                control.DataContextTypeStack = dataContext;
            }
            if (controlMetadata.DataContextConstraint != null && dataContext != null && !controlMetadata.DataContextConstraint.IsAssignableFrom(dataContext.DataContextType))
            {
                ((DothtmlNode)dataContextAttribute ?? element)
                .AddError($"The control '{controlMetadata.Type.Name}' requires a DataContext of type '{controlMetadata.DataContextConstraint.FullName}'!");
            }

            // set properties from attributes
            foreach (var attribute in element.Attributes.Where(a => a.AttributeName != "DataContext"))
            {
                ProcessAttribute(attribute, control, dataContext);
            }

            // process control contents
            ProcessControlContent(control, element.Content);

            // check required properties
            IAbstractPropertySetter missingProperty;
            var missingProperties = control.Metadata.AllProperties.Where(p => p.MarkupOptions.Required && !control.TryGetProperty(p, out missingProperty)).ToList();

            if (missingProperties.Any())
            {
                element.AddError($"The control '{ control.Metadata.Type.FullName }' is missing required properties: { string.Join(", ", missingProperties.Select(p => "'" + p.Name + "'")) }.");
            }
            return(control);
        }
示例#21
0
 protected override IDataContextStack CreateDataContextTypeStack(ITypeDescriptor viewModelType, ITypeDescriptor wrapperType = null, IDataContextStack parentDataContextStack = null, IReadOnlyList <NamespaceImport> namespaceImports = null)
 {
     return(new DataContextStack(
                ResolvedTypeDescriptor.ToSystemType(viewModelType),
                parentDataContextStack as DataContextStack,
                ResolvedTypeDescriptor.ToSystemType(wrapperType), namespaceImports));
 }
示例#22
0
 /// <summary>
 /// Creates the data context type stack object.
 /// </summary>
 protected abstract IDataContextStack CreateDataContextTypeStack(ITypeDescriptor viewModelType, IDataContextStack parentDataContextStack = null, IReadOnlyList <NamespaceImport> imports = null, IReadOnlyList <BindingExtensionParameter> extensionParameters = null);
示例#23
0
        /// <summary>
        /// Processes the attribute node.
        /// </summary>
        private void ProcessAttribute(DothtmlAttributeNode attribute, IAbstractControl control, IDataContextStack dataContext)
        {
            var name = attribute.AttributePrefix == null ? attribute.AttributeName : attribute.AttributePrefix + ":" + attribute.AttributeName;

            // find the property
            var property = controlResolver.FindProperty(control.Metadata, name);

            if (property != null)
            {
                if (property.IsBindingProperty || property.DataContextManipulationAttribute != null) // when DataContextManipulationAttribute is set, lets hope that author knows what is he doing.
                {
                    dataContext = GetDataContextChange(dataContext, control, property);
                }

                if (!property.MarkupOptions.MappingMode.HasFlag(MappingMode.Attribute))
                {
                    attribute.AddError($"The property '{property.FullName}' cannot be used as a control attribute!");
                    return;
                }

                // set the property
                if (attribute.ValueNode == null)
                {
                    // implicitly set boolean property
                    if (property.PropertyType.IsEqualTo(new ResolvedTypeDescriptor(typeof(bool))))
                    {
                        string error;
                        if (!treeBuilder.AddProperty(control, treeBuilder.BuildPropertyValue(property, true, attribute), out error))
                        {
                            attribute.AddError(error);
                        }
                    }
                    else if (property.MarkupOptions.AllowAttributeWithoutValue)
                    {
                        string error;
                        if (!treeBuilder.AddProperty(control, treeBuilder.BuildPropertyValue(property, (property as DotVVM.Framework.Binding.DotvvmProperty)?.DefaultValue, attribute), out error))
                        {
                            attribute.AddError(error);
                        }
                    }
                    else
                    {
                        attribute.AddError($"The attribute '{property.Name}' on the control '{control.Metadata.Type.FullName}' must have a value!");
                    }
                }
                else if (attribute.ValueNode is DothtmlValueBindingNode)
                {
                    // binding
                    var bindingNode = (attribute.ValueNode as DothtmlValueBindingNode).BindingNode;
                    if (property.IsVirtual && !property.IsBindingProperty && property.PropertyType.FullName != "System.Object")
                    {
                        attribute.ValueNode.AddError($"The property '{ property.FullName }' cannot contain bindings because it's not DotvvmProperty.");
                    }
                    else if (!treatBindingAsHardCodedValue.Contains(bindingNode.Name))
                    {
                        if (!property.MarkupOptions.AllowBinding)
                        {
                            attribute.ValueNode.AddError($"The property '{ property.FullName }' cannot contain {bindingNode.Name} binding.");
                        }
                    }
                    var    binding         = ProcessBinding(bindingNode, dataContext, property);
                    var    bindingProperty = treeBuilder.BuildPropertyBinding(property, binding, attribute);
                    string error;
                    if (!treeBuilder.AddProperty(control, bindingProperty, out error))
                    {
                        attribute.AddError(error);
                    }
                }
                else
                {
                    // hard-coded value in markup
                    if (!property.MarkupOptions.AllowHardCodedValue)
                    {
                        attribute.ValueNode.AddError($"The property '{ property.FullName }' cannot contain hard coded value.");
                    }

                    var    textValue     = attribute.ValueNode as DothtmlValueTextNode;
                    var    value         = ConvertValue(WebUtility.HtmlDecode(textValue.Text), property.PropertyType);
                    var    propertyValue = treeBuilder.BuildPropertyValue(property, value, attribute);
                    string error;
                    if (!treeBuilder.AddProperty(control, propertyValue, out error))
                    {
                        attribute.AddError(error);
                    }
                }
            }
            else
            {
                attribute.AddError($"The control '{control.Metadata.Type}' does not have a property '{attribute.AttributeName}' and does not allow HTML attributes!");
            }
        }
示例#24
0
 protected override IAbstractBinding CompileBinding(DothtmlBindingNode node, BindingParserOptions bindingOptions, IDataContextStack context, IPropertyDescriptor property)
 {
     if (context == null)
     {
         node.AddError("The DataContext couldn't be evaluated because of the errors above.");
     }
     return(treeBuilder.BuildBinding(bindingOptions, context, node, property));
 }
示例#25
0
 protected override IDataContextStack CreateDataContextTypeStack(ITypeDescriptor viewModelType, IDataContextStack parentDataContextStack = null, IReadOnlyList <NamespaceImport> namespaceImports = null, IReadOnlyList <BindingExtensionParameter> extensionParameters = null)
 {
     return(DataContextStack.Create(
                ResolvedTypeDescriptor.ToSystemType(viewModelType),
                parentDataContextStack as DataContextStack,
                namespaceImports, extensionParameters));
 }
示例#26
0
        private IAbstractControl ProcessText(DothtmlNode node, IControlResolverMetadata parentMetadata, IDataContextStack dataContext, DothtmlLiteralNode literalNode)
        {
            var whitespace = string.IsNullOrWhiteSpace(literalNode.Value);

            if (!whitespace)
            {
                EnsureContentAllowed(parentMetadata, node);
            }

            string text;

            if (literalNode.Escape)
            {
                text = WebUtility.HtmlEncode(literalNode.Value);
            }
            else
            {
                text = literalNode.Value;
            }

            var literal = treeBuilder.BuildControl(rawLiteralMetadata.Value, node, dataContext);

            literal.ConstructorParameters = new object[] { text, literalNode.Value, whitespace };
            return(literal);
        }
		public abstract IDataContextStack ChangeStackForChildren(IDataContextStack original, IAbstractControl control, IPropertyDescriptor property, Func<IDataContextStack, ITypeDescriptor, IDataContextStack> createNewFrame);
 public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
 {
     return(new ResolvedTypeDescriptor(type));
 }
示例#29
0
 public IAbstractControl BuildControl(IControlResolverMetadata metadata, DothtmlNode node, IDataContextStack dataContext)
 {
     return new ResolvedControl((ControlResolverMetadata)metadata, node, (DataContextStack)dataContext);
 }
示例#30
0
 public IAbstractTreeRoot BuildTreeRoot(IControlTreeResolver controlTreeResolver, IControlResolverMetadata metadata, DothtmlRootNode node, IDataContextStack dataContext, IReadOnlyDictionary <string, IReadOnlyList <IAbstractDirective> > directives)
 {
     return(new ResolvedTreeRoot((ControlResolverMetadata)metadata, node, (DataContextStack)dataContext, directives));
 }
示例#31
0
 public IAbstractTreeRoot BuildTreeRoot(IControlTreeResolver controlTreeResolver, IControlResolverMetadata metadata, DothtmlRootNode node, IDataContextStack dataContext)
 {
     return new ResolvedTreeRoot((ControlResolverMetadata)metadata, node, (DataContextStack)dataContext);
 }
示例#32
0
        /// <summary>
        /// Processes the template contents.
        /// </summary>
        private List <IAbstractControl> ProcessTemplate(IAbstractTreeNode parent, IEnumerable <DothtmlNode> elementContent, IDataContextStack dataContext)
        {
            var content = elementContent.Select(e => ProcessNode(parent, e, placeholderMetadata.Value, dataContext)).Where(e => e != null);

            return(content.ToList());
        }
示例#33
0
 public IAbstractControl BuildControl(IControlResolverMetadata metadata, DothtmlNode node, IDataContextStack dataContext)
 {
     return(new ResolvedControl((ControlResolverMetadata)metadata, node, (DataContextStack)dataContext));
 }
示例#34
0
        public static (ITypeDescriptor type, List <BindingExtensionParameter> extensionParameters) ApplyContextChange(IDataContextStack dataContext, DataContextChangeAttribute[] attributes, IAbstractControl control, IPropertyDescriptor property)
        {
            var type = dataContext.DataContextType;
            var extensionParameters = new List <BindingExtensionParameter>();

            foreach (var attribute in attributes.OrderBy(a => a.Order))
            {
                if (type == null)
                {
                    break;
                }
                extensionParameters.AddRange(attribute.GetExtensionParameters(type));
                type = attribute.GetChildDataContextType(type, dataContext, control, property);
            }
            return(type, extensionParameters);
        }
示例#35
0
        private void ProcessAttributeProperties(IAbstractControl control, DothtmlAttributeNode[] nodes, IDataContextStack dataContext)
        {
            var doneAttributes = new HashSet <DothtmlAttributeNode>();

            string getName(DothtmlAttributeNode n) => n.AttributePrefix == null ? n.AttributeName : n.AttributePrefix + ":" + n.AttributeName;

            void resolveAttribute(DothtmlAttributeNode attribute)
            {
                var name = getName(attribute);

                if (!doneAttributes.Add(attribute))
                {
                    return;
                }

                var property = controlResolver.FindProperty(control.Metadata, name);

                if (property == null)
                {
                    attribute.AddError($"The control '{control.Metadata.Type}' does not have a property '{attribute.AttributeName}' and does not allow HTML attributes!");
                }
                else
                {
                    var dependsOn = property.DataContextChangeAttributes.SelectMany(c => c.PropertyDependsOn);
                    foreach (var p in dependsOn.SelectMany(t => nodes.Where(n => t == getName(n))))
                    {
                        resolveAttribute(p);
                    }
                    ProcessAttribute(property, attribute, control, dataContext);
                }
            }

            // set properties from attributes
            foreach (var attr in nodes)
            {
                resolveAttribute(attr);
            }
        }
示例#36
0
 /// <summary>
 /// Compiles the binding.
 /// </summary>
 protected abstract IAbstractBinding CompileBinding(DothtmlBindingNode node, BindingParserOptions bindingOptions, IDataContextStack context, IPropertyDescriptor property);
 public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
 {
     return new ResolvedTypeDescriptor(type);
 }
示例#38
0
        protected override IAbstractBinding CompileBinding(DothtmlBindingNode node, BindingParserOptions bindingOptions, IDataContextStack context)
        {
            Expression      expression   = null;
            Exception       parsingError = null;
            ITypeDescriptor resultType   = null;

            if (context == null)
            {
                parsingError = new DotvvmCompilationException("The DataContext couldn't be evaluated because of the errors above.", node.Tokens);
            }
            else
            {
                try
                {
                    expression = bindingExpressionBuilder.Parse(node.Value, (DataContextStack)context, bindingOptions);
                    resultType = new ResolvedTypeDescriptor(expression.Type);
                }
                catch (Exception exception)
                {
                    parsingError = exception;
                }
            }
            return(treeBuilder.BuildBinding(bindingOptions, context, node, resultType, parsingError, expression));
        }
示例#39
0
 public abstract ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null);
		public override IDataContextStack ChangeStackForChildren(IDataContextStack original, IAbstractControl control, IPropertyDescriptor property, Func<IDataContextStack, ITypeDescriptor, IDataContextStack> createNewFrame)
		{
			return original.Parent;
		}
 public override ITypeDescriptor GetChildDataContextType(ITypeDescriptor dataContext, IDataContextStack controlContextStack, IAbstractControl control, IPropertyDescriptor property = null)
 {
     return TypeDescriptorUtils.GetCollectionItemType(dataContext);
 }