示例#1
0
 object IEntity.SetAttribute(string name, object value)
 {
     foreach (var comp in m_components)
     {
         if (comp is AttributeBag)
         {
             string[]     pair = name.Split('.');
             AttributeBag bag  = comp as AttributeBag;
             if (bag.Name == pair[0])
             {
                 return(bag.SetValue(pair[1], value));
             }
         }
     }
     return(null);
 }
示例#2
0
 public bool HasAttribute(string name)
 {
     return(AttributeBag.HasProperty(name));
 }
示例#3
0
 public string FindAttributeValue(string name)
 {
     return(AttributeBag.FindPropertyValue(name));
 }
示例#4
0
 public ParsedProperty FindAttribute(string name)
 {
     return(AttributeBag.FindProperty(name));
 }
示例#5
0
        /// <summary>
        /// Generates a grouped collection of <see cref="AutoInputMetadata"/> instances
        /// extracted from custom attributes of types <see cref="FormDisplayAttribute"/>
        /// and <see cref="FormDisplayDefaultAttribute"/> that decorate the specified
        /// <paramref name="type"/>.
        /// </summary>
        /// <param name="type">The type of the object from which to extract metadata.</param>
        /// <param name="instance">An instance of the specified <paramref name="type"/>.</param>
        /// <param name="result">Returns a grouped collection of <see cref="AutoInputMetadata"/> objects.</param>
        /// <returns></returns>
        public static bool ExtractMetadata(this Type type, object instance, out IReadOnlyCollection <FormDisplayGroupMetadata> result)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }

            if (!_sectionLayoutMetadataCache.TryGetValue(type, out var attributeBag))
            {
                attributeBag = new AttributeBag();
                var emptyDisplay      = FormDisplayAttribute.Empty;
                var properties        = type.GetProperties();
                var ignoreUndecorated = type.GetCustomAttribute <DisplayIgnoreAttribute>() != null;
                var defaultDisplay    = type.GetCustomAttributes <FormDisplayDefaultAttribute>().SingleOrDefault() ?? FormDisplayDefaultAttribute.Empty;

                foreach (var pi in properties)
                {
                    // only custom attributes descending from FormAttributeBase are discovered
                    var attributes    = pi.GetCustomAttributes <FormAttributeBase>(true).ToList();
                    var hasAttributes = attributes.Any();

                    if (!hasAttributes && ignoreUndecorated)
                    {
                        continue;
                    }

                    // DisplayIgnoreAttribute doesn't descend from FormAttributeBase;
                    // query the property info directly
                    var isIgnored = pi.GetCustomAttribute <DisplayIgnoreAttribute>() != null;

                    if (isIgnored)
                    {
                        continue;            // that simple, no questions asked!
                    }
                    var inputFileAttr = hasAttributes ? attributes.OfType <InputFileAttribute>().SingleOrDefault() : null;
                    var dragDropAttr  = hasAttributes ? attributes.OfType <DragDropAttribute>().SingleOrDefault() : null;

                    if (!(pi.CanRead && pi.CanWrite))
                    {
                        // check if the property is drag and drop enabled
                        // or an input file (no empty value is programmatically set on input file)
                        if (inputFileAttr == null && dragDropAttr == null)
                        {
                            continue; // properties must be read-write
                        }
                    }

                    var imageAttr = hasAttributes ? attributes.OfType <ImagePreviewAttribute>().SingleOrDefault() : null;
                    var formAttr  = hasAttributes ? attributes.OfType <FormDisplayAttribute>().SingleOrDefault() : null;

                    if (formAttr == null)
                    {
                        // check if it should be included for display
                        if (!ignoreUndecorated && !hasAttributes)
                        {
                            formAttr = defaultDisplay.CreateDefault();
                            attributes.Add(formAttr);
                        }
                    }

                    var hasInputFile = inputFileAttr != null || imageAttr != null;

                    if (imageAttr == null && (hasInputFile || formAttr?.UITypeHint == "file") && !pi.PropertyType.IsString())
                    {
                        throw new NotSupportedException(
                                  $"Property '{pi.Name}' for file input must be of type string." +
                                  $"The current type {pi.PropertyType} is unsupported");
                    }

                    if (formAttr != null)
                    {
                        if (formAttr.ColumnCssClass == null)
                        {
                            formAttr.ColumnCssClass = defaultDisplay.ColumnCssClass;
                        }

                        if (formAttr.CustomRenderMode == CustomRenderMode.Default)
                        {
                            formAttr.CustomRenderMode = defaultDisplay.CustomRenderMode;
                        }

                        if (formAttr.InputCssClass == null)
                        {
                            var css = defaultDisplay.InputCssClass ?? emptyDisplay.InputCssClass;
                            if (css == form_control)
                            {
                                // don't add by default 'form-control' class to the following input types
                                if (!__isRadioOrCheckbox())
                                {
                                    formAttr.InputCssClass = css;
                                }
                            }
                            else
                            {
                                formAttr.InputCssClass = css;
                            }
                        }
                        else if (formAttr.InputCssClass == form_control && __isRadioOrCheckbox())
                        {
                            formAttr.InputCssClass = null;
                        }

                        if (hasInputFile)
                        {
                            formAttr.UITypeHint = "file";

                            // give priority to ImagePreviewAttribute as it inherits InputFileAttribute
                            formAttr.FileAttribute = imageAttr ?? inputFileAttr;

                            if (imageAttr != null && imageAttr.TargetElementId == null)
                            {
                                imageAttr.TargetElementId = $"{pi.Name}{ImagePreviewAttribute.TargetElementIdSuffix}";
                            }
                        }

                        formAttr.DragDropAttribute = dragDropAttr;
                        formAttr.SetProperty(pi);

                        bool __isRadioOrCheckbox()
                        => formAttr.IsInputCheckboxOrRadio || pi.PropertyType.IsBoolean();
                    }

                    attributeBag.AddRange(pi.Name, attributes);
                }

                result = attributeBag.CreateGroupedDisplays(defaultDisplay, instance);
                _sectionLayoutMetadataCache[type] = attributeBag;
            }
            else
            {
                result = attributeBag.FormDisplayAttributeGroups;
                // refresh the model in all instances of AutoInputMetadata
                foreach (var group in result)
                {
                    foreach (var metadata in group.Items)
                    {
                        metadata.Refresh(instance);
                    }
                }
            }

            return(result != null);
        }