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); }
public bool HasAttribute(string name) { return(AttributeBag.HasProperty(name)); }
public string FindAttributeValue(string name) { return(AttributeBag.FindPropertyValue(name)); }
public ParsedProperty FindAttribute(string name) { return(AttributeBag.FindProperty(name)); }
/// <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); }