Hey, just an idea, suggestion, question, take you as you will...
Would it be possible to improve RadzenDataGridColumn
and generate it's Title
attribute from model properties' DisplayAttribute
? I would think this would not be that difficult for properties of the core model class but i'm not sure if it's difficult or even doable for nested classes inside of the model. The way I'm doing it right now:
Models:
public record TestDTO : DTO<int>
{
[Display(ResourceType = typeof(CommonRes), Description = nameof(CommonRes.Name))]
public string? Name { get; set; }
public GPSCoordsDTO Coords { get; set; } = new();
}
public record GPSCoordsDTO
{
[Display(ResourceType = typeof(CommonRes), Description = nameof(CommonRes.Latitude))]
public decimal Latitude { get; set; }
[Display(ResourceType = typeof(CommonRes), Description = nameof(CommonRes.Longitude))]
public decimal Longitude { get; set; }
}
Utility methods:
public static string? NameOfFull<T>(Expression<Func<T, object>> expression, char separator = '.')
{
ArgumentNullException.ThrowIfNull(expression);
MemberExpression? memberExpression = expression.Body as MemberExpression;
if(memberExpression is null)
{
UnaryExpression? unaryExpression = expression.Body as UnaryExpression;
if(unaryExpression is not null && unaryExpression.NodeType == ExpressionType.Convert)
memberExpression = unaryExpression.Operand as MemberExpression;
}
string? property = memberExpression?.ToString();
return property?[(property.IndexOf(separator) + 1)..];
}
public static string Display<T>(string propertyName)
{
ArgumentException.ThrowIfNullOrEmpty(propertyName, nameof(propertyName));
DisplayAttribute[] displayAttributes = (DisplayAttribute[])typeof(T)
.GetProperty(propertyName)!
.GetCustomAttributes(typeof(DisplayAttribute), false);
if(displayAttributes.Length > 0)
{
if(displayAttributes[0].ResourceType is null)
return displayAttributes[0].Description!;
else return new ResourceManager(displayAttributes[0].ResourceType!).GetString(displayAttributes[0].Description!)!;
}
else return propertyName;
}
Using it in the Razor components (a bit shortened for clarity):
<RadzenDataGrid>
<Columns>
<RadzenDataGridColumn
TItem="Type"
Property="@(NameOfFull<TestDTO>(x => x.Name!))"
Title="@(Display<TestDTO>(nameof(TestDTO.Name)))"
/>
<RadzenDataGridColumn
TItem="Type"
Property="@(NameOfFull<TestDTO>(x => x.Coords.Latitude))"
Title="@(Display<GPSCoordsDTO>(nameof(GPSCoordsDTO.Latitude)))"
/>
<RadzenDataGridColumn
TItem="Type"
Property="@(NameOfFull<TestDTO>(x => x.Coords.Longitude))"
Title="@(Display<GPSCoordsDTO>(nameof(GPSCoordsDTO.Longitude)))"
/>
</Columns>
</RadzenDataGrid>
This works fine, but it makes me wondering, if there is a need to always manually specify title at all. If the model is decorated with display attributes if it could be generated by RadzenDataGridColumn
component itself.
(The reason for having localized properties names in the model itself was initialy when i needed to automatically create exports for said model and didn't want to do another "binding" for CSV this time.)