mirror of https://github.com/abpframework/abp.git
13 changed files with 752 additions and 1 deletions
@ -0,0 +1,324 @@ |
|||
using Blazorise; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Linq; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.ObjectExtending; |
|||
using Volo.Abp.Reflection; |
|||
|
|||
namespace Volo.Abp.BlazoriseUI |
|||
{ |
|||
public static class BlazoriseUiObjectExtensionPropertyInfoExtensions |
|||
{ |
|||
private static readonly HashSet<Type> NumberTypes = new HashSet<Type> { |
|||
typeof(int), |
|||
typeof(long), |
|||
typeof(byte), |
|||
typeof(sbyte), |
|||
typeof(short), |
|||
typeof(ushort), |
|||
typeof(uint), |
|||
typeof(long), |
|||
typeof(ulong), |
|||
typeof(float), |
|||
typeof(double), |
|||
typeof(decimal), |
|||
typeof(int?), |
|||
typeof(long?), |
|||
typeof(byte?), |
|||
typeof(sbyte?), |
|||
typeof(short?), |
|||
typeof(ushort?), |
|||
typeof(uint?), |
|||
typeof(long?), |
|||
typeof(ulong?), |
|||
typeof(float?), |
|||
typeof(double?), |
|||
typeof(decimal?) |
|||
}; |
|||
|
|||
private static readonly HashSet<Type> TextEditSupportedAttributeTypes = new HashSet<Type> { |
|||
typeof(EmailAddressAttribute), |
|||
typeof(UrlAttribute), |
|||
typeof(PhoneAttribute) |
|||
}; |
|||
|
|||
public static string GetDateEditInputFormatOrNull(this IBasicObjectExtensionPropertyInfo property) |
|||
{ |
|||
if (property.IsDate()) |
|||
{ |
|||
return "{0:yyyy-MM-dd}"; |
|||
} |
|||
|
|||
if (property.IsDateTime()) |
|||
{ |
|||
return "{0:yyyy-MM-ddTHH:mm}"; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public static string GetTextInputValueOrNull(this IBasicObjectExtensionPropertyInfo property, object value) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
if (TypeHelper.IsFloatingType(property.Type)) |
|||
{ |
|||
return value.ToString()?.Replace(',', '.'); |
|||
} |
|||
|
|||
return value.ToString(); |
|||
} |
|||
|
|||
public static T GetInputValueOrDefault<T>(this IBasicObjectExtensionPropertyInfo property, object value) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
return default; |
|||
} |
|||
|
|||
return (T)value; |
|||
} |
|||
|
|||
public static bool GetBooleanInputValueOrDefault(this IBasicObjectExtensionPropertyInfo property, object value) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return (bool)value; |
|||
} |
|||
|
|||
public static DateTime? GetDateInputValueOrDefault(this IBasicObjectExtensionPropertyInfo property, object value) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
return default; |
|||
} |
|||
|
|||
return (DateTime?)value; |
|||
} |
|||
|
|||
public static TimeSpan? GetTimeInputValueOrDefault(this IBasicObjectExtensionPropertyInfo property, object value) |
|||
{ |
|||
if (value == null) |
|||
{ |
|||
return default; |
|||
} |
|||
|
|||
return (TimeSpan?)value; |
|||
} |
|||
|
|||
public static TextInputMode GetTextInputMode(this ObjectExtensionPropertyInfo propertyInfo) |
|||
{ |
|||
foreach (var attribute in propertyInfo.Attributes) |
|||
{ |
|||
var textRoleByAttribute = GetTextInputModeFromAttributeOrNull(attribute); |
|||
if (textRoleByAttribute != null) |
|||
{ |
|||
return textRoleByAttribute.Value; |
|||
} |
|||
} |
|||
|
|||
return GetTextInputModeFromTypeOrNull(propertyInfo.Type) |
|||
?? TextInputMode.None; //default
|
|||
} |
|||
|
|||
private static TextInputMode? GetTextInputModeFromTypeOrNull(Type type) |
|||
{ |
|||
if (TypeHelper.IsFloatingType(type)) |
|||
{ |
|||
return TextInputMode.Decimal; |
|||
} |
|||
|
|||
if (NumberTypes.Contains(type)) |
|||
{ |
|||
return TextInputMode.Numeric; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
private static TextInputMode? GetTextInputModeFromAttributeOrNull(Attribute attribute) |
|||
{ |
|||
if (attribute is EmailAddressAttribute) |
|||
{ |
|||
return TextInputMode.Email; |
|||
} |
|||
|
|||
if (attribute is UrlAttribute) |
|||
{ |
|||
return TextInputMode.Url; |
|||
} |
|||
|
|||
//if (attribute is HiddenInputAttribute)
|
|||
//{
|
|||
// return "hidden";
|
|||
//}
|
|||
|
|||
if (attribute is PhoneAttribute) |
|||
{ |
|||
return TextInputMode.Tel; |
|||
} |
|||
|
|||
if (attribute is DataTypeAttribute dataTypeAttribute) |
|||
{ |
|||
switch (dataTypeAttribute.DataType) |
|||
{ |
|||
case DataType.EmailAddress: |
|||
return TextInputMode.Email; |
|||
case DataType.Url: |
|||
return TextInputMode.Url; |
|||
case DataType.PhoneNumber: |
|||
return TextInputMode.Tel; |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public static TextRole GetTextRole(this ObjectExtensionPropertyInfo propertyInfo) |
|||
{ |
|||
foreach (var attribute in propertyInfo.Attributes) |
|||
{ |
|||
var textRoleByAttribute = GetTextRoleFromAttributeOrNull(attribute); |
|||
if (textRoleByAttribute != null) |
|||
{ |
|||
return textRoleByAttribute.Value; |
|||
} |
|||
} |
|||
|
|||
return TextRole.Text; //default
|
|||
} |
|||
|
|||
private static TextRole? GetTextRoleFromAttributeOrNull(Attribute attribute) |
|||
{ |
|||
if (attribute is EmailAddressAttribute) |
|||
{ |
|||
return TextRole.Email; |
|||
} |
|||
|
|||
if (attribute is UrlAttribute) |
|||
{ |
|||
return TextRole.Url; |
|||
} |
|||
|
|||
//if (attribute is HiddenInputAttribute)
|
|||
//{
|
|||
// return "hidden";
|
|||
//}
|
|||
|
|||
//if (attribute is PhoneAttribute)
|
|||
//{
|
|||
// return TextRole.Tel;
|
|||
//}
|
|||
|
|||
if (attribute is DataTypeAttribute dataTypeAttribute) |
|||
{ |
|||
switch (dataTypeAttribute.DataType) |
|||
{ |
|||
case DataType.Password: |
|||
return TextRole.Password; |
|||
case DataType.EmailAddress: |
|||
return TextRole.Email; |
|||
case DataType.Url: |
|||
return TextRole.Url; |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public static Type GetInputType(this ObjectExtensionPropertyInfo propertyInfo) |
|||
{ |
|||
foreach (var attribute in propertyInfo.Attributes) |
|||
{ |
|||
var inputTypeByAttribute = GetInputTypeFromAttributeOrNull(attribute); |
|||
if (inputTypeByAttribute != null) |
|||
{ |
|||
return inputTypeByAttribute; |
|||
} |
|||
} |
|||
return GetInputTypeFromTypeOrNull(propertyInfo.Type) |
|||
?? typeof(TextEdit); //default
|
|||
} |
|||
|
|||
private static Type GetInputTypeFromAttributeOrNull(Attribute attribute) |
|||
{ |
|||
var hasTextEditSupport = TextEditSupportedAttributeTypes.Any(t => t == attribute.GetType()); |
|||
|
|||
if (hasTextEditSupport) |
|||
{ |
|||
return typeof(TextEdit); |
|||
} |
|||
|
|||
//if (attribute is EmailAddressAttribute)
|
|||
//{
|
|||
// return TextInputMode.Email;
|
|||
//}
|
|||
|
|||
//if (attribute is UrlAttribute)
|
|||
//{
|
|||
// return TextInputMode.Url;
|
|||
//}
|
|||
|
|||
//if (attribute is HiddenInputAttribute)
|
|||
//{
|
|||
// return "hidden";
|
|||
//}
|
|||
|
|||
//if (attribute is PhoneAttribute)
|
|||
//{
|
|||
// return TextInputMode.Tel;
|
|||
//}
|
|||
|
|||
if (attribute is DataTypeAttribute dataTypeAttribute) |
|||
{ |
|||
switch (dataTypeAttribute.DataType) |
|||
{ |
|||
case DataType.Password: |
|||
return typeof(TextEdit); |
|||
case DataType.Date: |
|||
return typeof(DateEdit<>); |
|||
case DataType.Time: |
|||
return typeof(TimeEdit<>); |
|||
case DataType.EmailAddress: |
|||
return typeof(TextEdit); |
|||
case DataType.Url: |
|||
return typeof(TextEdit); |
|||
case DataType.PhoneNumber: |
|||
return typeof(TextEdit); |
|||
case DataType.DateTime: |
|||
return typeof(DateEdit<>); |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
private static Type GetInputTypeFromTypeOrNull(Type type) |
|||
{ |
|||
if (type == typeof(bool)) |
|||
{ |
|||
return typeof(Check<>); |
|||
} |
|||
|
|||
if (type == typeof(DateTime)) |
|||
{ |
|||
return typeof(DateEdit<>); |
|||
} |
|||
|
|||
if (NumberTypes.Contains(type)) |
|||
{ |
|||
return typeof(TextEdit); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
@typeparam TEntityType |
|||
@typeparam TResourceType |
|||
@using Volo.Abp.ObjectExtending |
|||
@using Volo.Abp.Localization |
|||
@using Volo.Abp.Data |
|||
|
|||
@foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties<TEntityType>()) |
|||
{ |
|||
if (!propertyInfo.Name.EndsWith("_Text")) |
|||
{ |
|||
if (propertyInfo.Type.IsEnum) |
|||
{ |
|||
<SelectExtensionProperty PropertyInfo="@propertyInfo" Entity="@Entity" TEntity="TEntityType" TResourceType="TResourceType" /> |
|||
} |
|||
else if (!propertyInfo.Lookup.Url.IsNullOrEmpty()) |
|||
{ |
|||
<LookupExtensionProperty PropertyInfo="@propertyInfo" Entity="@Entity" TEntity="TEntityType" TResourceType="TResourceType" /> |
|||
|
|||
} |
|||
else |
|||
{ |
|||
var inputType = propertyInfo.GetInputType(); |
|||
if (inputType == typeof(TextEdit)) |
|||
{ |
|||
<TextExtensionProperty TEntity="TEntityType" TResourceType="TResourceType" PropertyInfo="@propertyInfo" Entity="@Entity"> |
|||
|
|||
</TextExtensionProperty> |
|||
} |
|||
else if (inputType == typeof(Check<>)) |
|||
{ |
|||
<Field> |
|||
<Check TValue="bool" CheckedChanged="(val) => CheckedChanged(val, propertyInfo.Name)" Checked="@(propertyInfo.GetInputValueOrDefault<bool>(Entity.GetProperty(propertyInfo.Name)))">@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</Check> |
|||
</Field> |
|||
} |
|||
else if (inputType == typeof(TimeEdit<>)) |
|||
{ |
|||
<Field> |
|||
<FieldLabel>@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>--> |
|||
<TimeEdit TValue="TimeSpan?" Time="@(propertyInfo.GetInputValueOrDefault<TimeSpan?>(Entity.GetProperty(propertyInfo.Name)))" TimeChanged="(val) => TimeChanged(val, propertyInfo.Name)"> |
|||
<Feedback> |
|||
<ValidationError /> |
|||
</Feedback> |
|||
</TimeEdit> |
|||
</Field> |
|||
} |
|||
else if (inputType == typeof(DateEdit<>)) |
|||
{ |
|||
<Field> |
|||
<FieldLabel>@propertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel> |
|||
<DateEdit TValue="DateTime?" |
|||
Pattern="@propertyInfo.GetDateEditInputFormatOrNull()" |
|||
Date="@(propertyInfo.GetInputValueOrDefault<DateTime?>(Entity.GetProperty(propertyInfo.Name)))" |
|||
DateChanged="(val) => DateTimeChanged(val, propertyInfo.Name)"> |
|||
<Feedback> |
|||
<ValidationError /> |
|||
</Feedback> |
|||
</DateEdit> |
|||
</Field> |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
using Microsoft.AspNetCore.Components; |
|||
using Microsoft.Extensions.Localization; |
|||
using System; |
|||
using Volo.Abp.AspNetCore.Components.WebAssembly; |
|||
using Volo.Abp.Data; |
|||
|
|||
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending |
|||
{ |
|||
public partial class ExtensionProperties<TEntityType, TResourceType> : ComponentBase |
|||
where TEntityType : IHasExtraProperties |
|||
{ |
|||
[Inject] |
|||
public IStringLocalizerFactory StringLocalizerFactory { get; set; } |
|||
|
|||
[Parameter] |
|||
public AbpBlazorMessageLocalizerHelper<TResourceType> LH { get; set; } |
|||
|
|||
[Parameter] |
|||
public TEntityType Entity { get; set; } |
|||
|
|||
protected void TextChanged(string value, string propertyName) |
|||
{ |
|||
Entity.SetProperty(propertyName, value); |
|||
} |
|||
|
|||
protected void CheckedChanged(bool value, string propertyName) |
|||
{ |
|||
Entity.SetProperty(propertyName, value); |
|||
} |
|||
|
|||
protected void TimeChanged(TimeSpan? value, string propertyName) |
|||
{ |
|||
Entity.SetProperty(propertyName, value); |
|||
} |
|||
|
|||
protected void DateTimeChanged(DateTime? value, string propertyName) |
|||
{ |
|||
Entity.SetProperty(propertyName, value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
@typeparam TEntity |
|||
@typeparam TResourceType |
|||
@using Abp.Localization |
|||
@using Blazorise.Components |
|||
|
|||
<Field> |
|||
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel> |
|||
<Autocomplete Data="@lookupItems" |
|||
TItem="SelectItem<object>" |
|||
TValue="object" |
|||
TextField="item=>item.Text" |
|||
ValueField="item=>item.Value" |
|||
@bind-SelectedValue="@SelectedValue" |
|||
SearchChanged="@SearchFilterChangedAsync"> |
|||
</Autocomplete> |
|||
</Field> |
|||
@ -0,0 +1,92 @@ |
|||
using Microsoft.AspNetCore.Components; |
|||
using Microsoft.Extensions.Localization; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Net.Http; |
|||
using System.Text.Json; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.ObjectExtending; |
|||
|
|||
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending |
|||
{ |
|||
public partial class LookupExtensionProperty<TEntity, TResourceType> : ComponentBase |
|||
where TEntity : IHasExtraProperties |
|||
{ |
|||
protected List<SelectItem<object>> lookupItems; |
|||
|
|||
[Inject] |
|||
public IStringLocalizerFactory StringLocalizerFactory { get; set; } |
|||
|
|||
[Inject] |
|||
public HttpClient Client { get; set; } |
|||
|
|||
[Parameter] |
|||
public TEntity Entity { get; set; } |
|||
|
|||
[Parameter] |
|||
public ObjectExtensionPropertyInfo PropertyInfo { get; set; } |
|||
|
|||
public object SelectedValue |
|||
{ |
|||
get |
|||
{ |
|||
return Entity.GetProperty(PropertyInfo.Name); |
|||
} |
|||
set |
|||
{ |
|||
Entity.SetProperty(PropertyInfo.Name, value); |
|||
UpdateLookupTextProperty(value); |
|||
} |
|||
} |
|||
|
|||
|
|||
public LookupExtensionProperty() |
|||
{ |
|||
lookupItems = new List<SelectItem<object>>(); |
|||
} |
|||
|
|||
protected override async Task OnInitializedAsync() |
|||
{ |
|||
lookupItems = await GetLookupItemsAsync(string.Empty); |
|||
} |
|||
|
|||
protected virtual void UpdateLookupTextProperty(object value) |
|||
{ |
|||
var lookupPropertyName = $"{PropertyInfo.Name}_Text"; |
|||
var selectedItemText = lookupItems.SingleOrDefault(t => t.Value.Equals(value)).Text; |
|||
Entity.SetProperty(lookupPropertyName, selectedItemText); |
|||
} |
|||
|
|||
protected virtual async Task<List<SelectItem<object>>> GetLookupItemsAsync(string filter) |
|||
{ |
|||
var selectItems = new List<SelectItem<object>>(); |
|||
var url = PropertyInfo.Lookup.Url; |
|||
if (!filter.IsNullOrEmpty()) |
|||
{ |
|||
url += $"{PropertyInfo.Lookup.FilterParamName}={filter.Trim()}"; |
|||
} |
|||
|
|||
var responseStream = await Client.GetStreamAsync(url); |
|||
|
|||
var document = await JsonDocument.ParseAsync(responseStream); |
|||
var itemsArrayProp = document.RootElement.GetProperty(PropertyInfo.Lookup.ResultListPropertyName); |
|||
foreach (var item in itemsArrayProp.EnumerateArray()) |
|||
{ |
|||
selectItems.Add(new SelectItem<object> |
|||
{ |
|||
Text = item.GetProperty(PropertyInfo.Lookup.DisplayPropertyName).GetString(), |
|||
Value = JsonSerializer.Deserialize(item.GetProperty(PropertyInfo.Lookup.ValuePropertyName).GetRawText(), PropertyInfo.Type) |
|||
}); |
|||
} |
|||
|
|||
return selectItems; |
|||
} |
|||
|
|||
protected virtual async Task SearchFilterChangedAsync(string filter) |
|||
{ |
|||
lookupItems = await GetLookupItemsAsync(filter); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
@typeparam TEntity |
|||
@typeparam TResourceType |
|||
@using Abp.Localization |
|||
|
|||
<Field> |
|||
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel> |
|||
<Select TValue="int" SelectedValue="@SelectedValue" SelectedValueChanged="@SelectedValueChanged"> |
|||
@foreach (var item in GetSelectItemsFromEnum()) |
|||
{ |
|||
<SelectItem Value="@item.Value">@item.Text</SelectItem> |
|||
} |
|||
</Select> |
|||
</Field> |
|||
@ -0,0 +1,84 @@ |
|||
using Microsoft.AspNetCore.Components; |
|||
using Microsoft.Extensions.Localization; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.ObjectExtending; |
|||
|
|||
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending |
|||
{ |
|||
public partial class SelectExtensionProperty<TEntity, TResourceType> : ComponentBase |
|||
where TEntity : IHasExtraProperties |
|||
{ |
|||
[Inject] |
|||
public IStringLocalizerFactory StringLocalizerFactory { get; set; } |
|||
|
|||
[Parameter] |
|||
public TEntity Entity { get; set; } |
|||
|
|||
[Parameter] |
|||
public ObjectExtensionPropertyInfo PropertyInfo { get; set; } |
|||
|
|||
public int SelectedValue |
|||
{ |
|||
get |
|||
{ |
|||
return Entity.GetProperty<int>(PropertyInfo.Name); |
|||
} |
|||
set |
|||
{ |
|||
Entity.SetProperty(PropertyInfo.Name, value); |
|||
} |
|||
} |
|||
|
|||
protected virtual IEnumerable<SelectItem<int>> GetSelectItemsFromEnum() |
|||
{ |
|||
var isNullableType = Nullable.GetUnderlyingType(PropertyInfo.Type) != null; |
|||
var enumType = PropertyInfo.Type; |
|||
|
|||
if (isNullableType) |
|||
{ |
|||
enumType = Nullable.GetUnderlyingType(PropertyInfo.Type); |
|||
yield return new SelectItem<int>(); |
|||
} |
|||
|
|||
foreach (var enumValue in enumType.GetEnumValues()) |
|||
{ |
|||
var memberName = enumType.GetEnumName(enumValue); |
|||
var localizedMemberName = AbpInternalLocalizationHelper.LocalizeWithFallback( |
|||
new[] |
|||
{ |
|||
// containerLocalizer,
|
|||
StringLocalizerFactory.CreateDefaultOrNull() |
|||
}, |
|||
new[] |
|||
{ |
|||
$"Enum:{enumType.Name}.{memberName}", |
|||
$"{enumType.Name}.{memberName}", |
|||
memberName |
|||
}, |
|||
memberName |
|||
); |
|||
|
|||
yield return new SelectItem<int> |
|||
{ |
|||
Value = (int)enumValue, |
|||
Text = localizedMemberName |
|||
}; |
|||
} |
|||
} |
|||
|
|||
|
|||
protected virtual void SelectedValueChanged(int value) |
|||
{ |
|||
SelectedValue = value; |
|||
} |
|||
} |
|||
|
|||
public class SelectItem<TValue> |
|||
{ |
|||
public string Text { get; set; } |
|||
public TValue Value { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
@typeparam TEntity |
|||
@typeparam TResourceType |
|||
@using Volo.Abp.BlazoriseUI |
|||
@using Volo.Abp.Localization |
|||
|
|||
@if (PropertyInfo != null && Entity != null) |
|||
{ |
|||
<Field> |
|||
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel> |
|||
<TextEdit @bind-Text="@Value" Role="@PropertyInfo.GetTextRole()" InputMode="@PropertyInfo.GetTextInputMode()"> |
|||
<Feedback> |
|||
<ValidationError /> |
|||
</Feedback> |
|||
</TextEdit> |
|||
</Field> |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using Microsoft.AspNetCore.Components; |
|||
using Microsoft.Extensions.Localization; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.ObjectExtending; |
|||
|
|||
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending |
|||
{ |
|||
public partial class TextExtensionProperty<TEntity, TResourceType> : ComponentBase |
|||
where TEntity : IHasExtraProperties |
|||
{ |
|||
[Inject] |
|||
public IStringLocalizerFactory StringLocalizerFactory { get; set; } |
|||
|
|||
[Parameter] |
|||
public TEntity Entity { get; set; } |
|||
|
|||
[Parameter] |
|||
public ObjectExtensionPropertyInfo PropertyInfo { get; set; } |
|||
|
|||
|
|||
protected string Value |
|||
{ |
|||
get |
|||
{ |
|||
return PropertyInfo.GetTextInputValueOrNull(Entity.GetProperty(PropertyInfo.Name)); |
|||
} |
|||
set |
|||
{ |
|||
Entity.SetProperty(PropertyInfo.Name, value); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.ObjectExtending |
|||
{ |
|||
public static class ObjectExtensionPropertyInfoBlazorExtensions |
|||
{ |
|||
private static readonly Type[] DateTimeTypes = |
|||
{ |
|||
typeof(DateTime), |
|||
typeof(DateTime?), |
|||
typeof(DateTimeOffset), |
|||
typeof(DateTimeOffset?) |
|||
}; |
|||
|
|||
public static bool IsDate(this IBasicObjectExtensionPropertyInfo property) |
|||
{ |
|||
return DateTimeTypes.Contains(property.Type) && |
|||
property.GetDataTypeOrNull() == DataType.Date; |
|||
} |
|||
|
|||
public static bool IsDateTime(this IBasicObjectExtensionPropertyInfo property) |
|||
{ |
|||
return DateTimeTypes.Contains(property.Type) && |
|||
!property.IsDate(); |
|||
} |
|||
|
|||
public static DataType? GetDataTypeOrNull(this IBasicObjectExtensionPropertyInfo property) |
|||
{ |
|||
return property |
|||
.Attributes |
|||
.OfType<DataTypeAttribute>() |
|||
.FirstOrDefault()?.DataType; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue