703 lines
30 KiB
Plaintext
703 lines
30 KiB
Plaintext
@using DevExpress.Blazor
|
|
@using Microsoft.AspNetCore.Components.Rendering
|
|
@using System.Reflection
|
|
@typeparam TDataItem where TDataItem : class
|
|
|
|
<div class="mg-grid-info-panel @(_isEditMode ? "edit-mode" : "view-mode")">
|
|
@if (GetActiveDataItem() != null && _currentGrid != null)
|
|
{
|
|
var colSpan = _allDataColumns.Count > 10 ? 6 : 12;
|
|
var dataItem = GetActiveDataItem()!;
|
|
|
|
<DxFormLayout CssClass="info-panel-form"
|
|
CaptionPosition="CaptionPosition.Vertical"
|
|
SizeMode="SizeMode.Small">
|
|
@foreach (var column in _allDataColumns)
|
|
{
|
|
var displayText = GetDisplayTextFromGrid(column);
|
|
var value = GetCellValue(column);
|
|
var settingsType = GetEditSettingsType(column);
|
|
var isReadOnly = !_isEditMode || column.ReadOnly;
|
|
|
|
<DxFormLayoutItem Caption="@GetColumnCaption(column)"
|
|
CaptionCssClass="@GetCaptionCssClass(isReadOnly)"
|
|
ColSpanXxl="@colSpan"
|
|
ColSpanXl="@colSpan"
|
|
ColSpanLg="@colSpan"
|
|
ColSpanMd="@colSpan"
|
|
ColSpanSm="@colSpan"
|
|
ColSpanXs="@colSpan">
|
|
<Template>
|
|
@if (_isEditMode && !column.ReadOnly)
|
|
{
|
|
@RenderEditableCell(column, dataItem, value, displayText, settingsType)
|
|
}
|
|
else
|
|
{
|
|
@RenderCellContent(column, value, displayText, settingsType)
|
|
}
|
|
</Template>
|
|
</DxFormLayoutItem>
|
|
}
|
|
</DxFormLayout>
|
|
}
|
|
else
|
|
{
|
|
<div class="info-panel-empty">
|
|
<p>Válasszon ki egy sort az adatok megtekintéséhez</p>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
@code {
|
|
private string GetColumnCaption(DxGridDataColumn column)
|
|
{
|
|
return !string.IsNullOrWhiteSpace(column.Caption) ? column.Caption : column.FieldName;
|
|
}
|
|
|
|
private string GetCaptionCssClass(bool isReadOnly)
|
|
{
|
|
return isReadOnly ? "fw-semibold" : "fw-semibold text-primary";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Renders an editable cell with two-way binding to the EditModel
|
|
/// </summary>
|
|
private RenderFragment RenderEditableCell(DxGridDataColumn column, TDataItem dataItem, object? value, string displayText, EditSettingsType settingsType)
|
|
{
|
|
return builder =>
|
|
{
|
|
var seq = 0;
|
|
var fieldName = column.FieldName;
|
|
var propertyInfo = typeof(TDataItem).GetProperty(fieldName);
|
|
|
|
if (propertyInfo == null)
|
|
{
|
|
// Fallback to readonly if property not found
|
|
RenderCellContent(column, value, displayText, settingsType)(builder);
|
|
return;
|
|
}
|
|
|
|
var propertyType = propertyInfo.PropertyType;
|
|
var underlyingType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;
|
|
|
|
// ComboBox columns
|
|
if (settingsType == EditSettingsType.ComboBox)
|
|
{
|
|
var comboSettings = GetEditSettings(fieldName) as DxComboBoxSettings;
|
|
if (comboSettings != null)
|
|
{
|
|
RenderComboBoxEditor(builder, ref seq, dataItem, propertyInfo, comboSettings);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Render based on property type
|
|
if (underlyingType == typeof(bool))
|
|
{
|
|
RenderCheckBoxEditor(builder, ref seq, dataItem, propertyInfo);
|
|
}
|
|
else if (underlyingType == typeof(DateTime))
|
|
{
|
|
RenderDateTimeEditor(builder, ref seq, dataItem, propertyInfo, column.DisplayFormat);
|
|
}
|
|
else if (underlyingType == typeof(DateOnly))
|
|
{
|
|
RenderDateOnlyEditor(builder, ref seq, dataItem, propertyInfo, column.DisplayFormat);
|
|
}
|
|
else if (underlyingType == typeof(TimeOnly))
|
|
{
|
|
RenderTimeOnlyEditor(builder, ref seq, dataItem, propertyInfo);
|
|
}
|
|
else if (underlyingType == typeof(TimeSpan))
|
|
{
|
|
RenderTimeSpanEditor(builder, ref seq, dataItem, propertyInfo);
|
|
}
|
|
else if (underlyingType == typeof(int))
|
|
{
|
|
RenderSpinIntEditor(builder, ref seq, dataItem, propertyInfo);
|
|
}
|
|
else if (underlyingType == typeof(decimal))
|
|
{
|
|
RenderSpinDecimalEditor(builder, ref seq, dataItem, propertyInfo);
|
|
}
|
|
else if (underlyingType == typeof(double))
|
|
{
|
|
RenderSpinDoubleEditor(builder, ref seq, dataItem, propertyInfo);
|
|
}
|
|
else if (settingsType == EditSettingsType.Memo || (propertyType == typeof(string) && fieldName.Contains("Comment", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
RenderMemoEditor(builder, ref seq, dataItem, propertyInfo);
|
|
}
|
|
else
|
|
{
|
|
RenderTextBoxEditor(builder, ref seq, dataItem, propertyInfo);
|
|
}
|
|
};
|
|
}
|
|
|
|
private void RenderCheckBoxEditor(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo)
|
|
{
|
|
var currentValue = (bool)(propertyInfo.GetValue(dataItem) ?? false);
|
|
|
|
builder.OpenComponent<DxCheckBox<bool>>(seq++);
|
|
builder.AddAttribute(seq++, "Checked", currentValue);
|
|
builder.AddAttribute(seq++, "CheckedChanged", EventCallback.Factory.Create<bool>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderDateTimeEditor(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo, string? displayFormat)
|
|
{
|
|
var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
|
|
var currentValue = propertyInfo.GetValue(dataItem);
|
|
|
|
if (isNullable)
|
|
{
|
|
builder.OpenComponent<DxDateEdit<DateTime?>>(seq++);
|
|
builder.AddAttribute(seq++, "Date", (DateTime?)currentValue);
|
|
builder.AddAttribute(seq++, "DateChanged", EventCallback.Factory.Create<DateTime?>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
builder.OpenComponent<DxDateEdit<DateTime>>(seq++);
|
|
builder.AddAttribute(seq++, "Date", (DateTime)(currentValue ?? DateTime.MinValue));
|
|
builder.AddAttribute(seq++, "DateChanged", EventCallback.Factory.Create<DateTime>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
builder.AddAttribute(seq++, "DisplayFormat", displayFormat ?? "yyyy-MM-dd HH:mm");
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderDateOnlyEditor(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo, string? displayFormat)
|
|
{
|
|
var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
|
|
var currentValue = propertyInfo.GetValue(dataItem);
|
|
|
|
if (isNullable)
|
|
{
|
|
builder.OpenComponent<DxDateEdit<DateOnly?>>(seq++);
|
|
builder.AddAttribute(seq++, "Date", (DateOnly?)currentValue);
|
|
builder.AddAttribute(seq++, "DateChanged", EventCallback.Factory.Create<DateOnly?>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
builder.OpenComponent<DxDateEdit<DateOnly>>(seq++);
|
|
builder.AddAttribute(seq++, "Date", (DateOnly)(currentValue ?? DateOnly.MinValue));
|
|
builder.AddAttribute(seq++, "DateChanged", EventCallback.Factory.Create<DateOnly>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
builder.AddAttribute(seq++, "DisplayFormat", displayFormat ?? "yyyy-MM-dd");
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderTimeOnlyEditor(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo)
|
|
{
|
|
var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
|
|
var currentValue = propertyInfo.GetValue(dataItem);
|
|
|
|
if (isNullable)
|
|
{
|
|
builder.OpenComponent<DxTimeEdit<TimeOnly?>>(seq++);
|
|
builder.AddAttribute(seq++, "Time", (TimeOnly?)currentValue);
|
|
builder.AddAttribute(seq++, "TimeChanged", EventCallback.Factory.Create<TimeOnly?>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
builder.OpenComponent<DxTimeEdit<TimeOnly>>(seq++);
|
|
builder.AddAttribute(seq++, "Time", (TimeOnly)(currentValue ?? TimeOnly.MinValue));
|
|
builder.AddAttribute(seq++, "TimeChanged", EventCallback.Factory.Create<TimeOnly>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderTimeSpanEditor(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo)
|
|
{
|
|
var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
|
|
var currentValue = propertyInfo.GetValue(dataItem);
|
|
|
|
if (isNullable)
|
|
{
|
|
builder.OpenComponent<DxTimeEdit<TimeSpan?>>(seq++);
|
|
builder.AddAttribute(seq++, "Time", (TimeSpan?)currentValue);
|
|
builder.AddAttribute(seq++, "TimeChanged", EventCallback.Factory.Create<TimeSpan?>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
builder.OpenComponent<DxTimeEdit<TimeSpan>>(seq++);
|
|
builder.AddAttribute(seq++, "Time", (TimeSpan)(currentValue ?? TimeSpan.Zero));
|
|
builder.AddAttribute(seq++, "TimeChanged", EventCallback.Factory.Create<TimeSpan>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderSpinIntEditor(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo)
|
|
{
|
|
var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
|
|
var currentValue = propertyInfo.GetValue(dataItem);
|
|
|
|
if (isNullable)
|
|
{
|
|
builder.OpenComponent<DxSpinEdit<int?>>(seq++);
|
|
builder.AddAttribute(seq++, "Value", (int?)currentValue);
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<int?>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
builder.OpenComponent<DxSpinEdit<int>>(seq++);
|
|
builder.AddAttribute(seq++, "Value", (int)(currentValue ?? 0));
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<int>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderSpinDecimalEditor(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo)
|
|
{
|
|
var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
|
|
var currentValue = propertyInfo.GetValue(dataItem);
|
|
|
|
if (isNullable)
|
|
{
|
|
builder.OpenComponent<DxSpinEdit<decimal?>>(seq++);
|
|
builder.AddAttribute(seq++, "Value", (decimal?)currentValue);
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<decimal?>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
builder.OpenComponent<DxSpinEdit<decimal>>(seq++);
|
|
builder.AddAttribute(seq++, "Value", (decimal)(currentValue ?? 0m));
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<decimal>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderSpinDoubleEditor(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo)
|
|
{
|
|
var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
|
|
var currentValue = propertyInfo.GetValue(dataItem);
|
|
|
|
if (isNullable)
|
|
{
|
|
builder.OpenComponent<DxSpinEdit<double?>>(seq++);
|
|
builder.AddAttribute(seq++, "Value", (double?)currentValue);
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<double?>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
builder.OpenComponent<DxSpinEdit<double>>(seq++);
|
|
builder.AddAttribute(seq++, "Value", (double)(currentValue ?? 0d));
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<double>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
}
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderTextBoxEditor(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo)
|
|
{
|
|
var currentValue = propertyInfo.GetValue(dataItem)?.ToString() ?? string.Empty;
|
|
|
|
builder.OpenComponent<DxTextBox>(seq++);
|
|
builder.AddAttribute(seq++, "Text", currentValue);
|
|
builder.AddAttribute(seq++, "TextChanged", EventCallback.Factory.Create<string>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderMemoEditor(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo)
|
|
{
|
|
var currentValue = propertyInfo.GetValue(dataItem)?.ToString() ?? string.Empty;
|
|
|
|
builder.OpenComponent<DxMemo>(seq++);
|
|
builder.AddAttribute(seq++, "Text", currentValue);
|
|
builder.AddAttribute(seq++, "TextChanged", EventCallback.Factory.Create<string>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
InvokeAsync(StateHasChanged);
|
|
}));
|
|
builder.AddAttribute(seq++, "Rows", 3);
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderComboBoxEditor(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo, DxComboBoxSettings settings)
|
|
{
|
|
var currentValue = propertyInfo.GetValue(dataItem);
|
|
var propertyType = propertyInfo.PropertyType;
|
|
var underlyingType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;
|
|
|
|
// Determine TData type from settings.Data
|
|
var dataType = settings.Data?.GetType();
|
|
var itemType = typeof(object);
|
|
if (dataType != null && dataType.IsGenericType)
|
|
{
|
|
var genericArgs = dataType.GetGenericArguments();
|
|
if (genericArgs.Length > 0)
|
|
{
|
|
itemType = genericArgs[0];
|
|
}
|
|
}
|
|
|
|
// Handle common value types for FK fields
|
|
if (underlyingType == typeof(int))
|
|
{
|
|
RenderComboBoxInt(builder, ref seq, dataItem, propertyInfo, settings, itemType, currentValue);
|
|
}
|
|
else if (underlyingType == typeof(long))
|
|
{
|
|
RenderComboBoxLong(builder, ref seq, dataItem, propertyInfo, settings, itemType, currentValue);
|
|
}
|
|
else if (underlyingType == typeof(Guid))
|
|
{
|
|
RenderComboBoxGuid(builder, ref seq, dataItem, propertyInfo, settings, itemType, currentValue);
|
|
}
|
|
else
|
|
{
|
|
// Fallback: render as TextBox with display text
|
|
var displayText = ResolveComboBoxDisplayText(settings, currentValue ?? new object()) ?? currentValue?.ToString() ?? string.Empty;
|
|
builder.OpenComponent<DxTextBox>(seq++);
|
|
builder.AddAttribute(seq++, "Text", displayText);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
}
|
|
}
|
|
|
|
private void RenderComboBoxInt(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo, DxComboBoxSettings settings, Type itemType, object? currentValue)
|
|
{
|
|
var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
|
|
|
|
// Create the generic ComboBox type: DxComboBox<TItem, int> or DxComboBox<TItem, int?>
|
|
var comboType = isNullable
|
|
? typeof(DxComboBox<,>).MakeGenericType(itemType, typeof(int?))
|
|
: typeof(DxComboBox<,>).MakeGenericType(itemType, typeof(int));
|
|
|
|
builder.OpenComponent(seq++, comboType);
|
|
builder.AddAttribute(seq++, "Data", settings.Data);
|
|
builder.AddAttribute(seq++, "ValueFieldName", settings.ValueFieldName);
|
|
builder.AddAttribute(seq++, "TextFieldName", settings.TextFieldName);
|
|
|
|
if (isNullable)
|
|
{
|
|
builder.AddAttribute(seq++, "Value", currentValue as int?);
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<int?>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
StateHasChanged();
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
builder.AddAttribute(seq++, "Value", currentValue is int intVal ? intVal : 0);
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<int>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
StateHasChanged();
|
|
}));
|
|
}
|
|
|
|
builder.AddAttribute(seq++, "ClearButtonDisplayMode", DataEditorClearButtonDisplayMode.Auto);
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderComboBoxLong(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo, DxComboBoxSettings settings, Type itemType, object? currentValue)
|
|
{
|
|
var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
|
|
|
|
var comboType = isNullable
|
|
? typeof(DxComboBox<,>).MakeGenericType(itemType, typeof(long?))
|
|
: typeof(DxComboBox<,>).MakeGenericType(itemType, typeof(long));
|
|
|
|
builder.OpenComponent(seq++, comboType);
|
|
builder.AddAttribute(seq++, "Data", settings.Data);
|
|
builder.AddAttribute(seq++, "ValueFieldName", settings.ValueFieldName);
|
|
builder.AddAttribute(seq++, "TextFieldName", settings.TextFieldName);
|
|
|
|
if (isNullable)
|
|
{
|
|
builder.AddAttribute(seq++, "Value", currentValue as long?);
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<long?>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
StateHasChanged();
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
builder.AddAttribute(seq++, "Value", currentValue is long longVal ? longVal : 0L);
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<long>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
StateHasChanged();
|
|
}));
|
|
}
|
|
|
|
builder.AddAttribute(seq++, "ClearButtonDisplayMode", DataEditorClearButtonDisplayMode.Auto);
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private void RenderComboBoxGuid(RenderTreeBuilder builder, ref int seq, TDataItem dataItem, PropertyInfo propertyInfo, DxComboBoxSettings settings, Type itemType, object? currentValue)
|
|
{
|
|
var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null;
|
|
|
|
var comboType = isNullable
|
|
? typeof(DxComboBox<,>).MakeGenericType(itemType, typeof(Guid?))
|
|
: typeof(DxComboBox<,>).MakeGenericType(itemType, typeof(Guid));
|
|
|
|
builder.OpenComponent(seq++, comboType);
|
|
builder.AddAttribute(seq++, "Data", settings.Data);
|
|
builder.AddAttribute(seq++, "ValueFieldName", settings.ValueFieldName);
|
|
builder.AddAttribute(seq++, "TextFieldName", settings.TextFieldName);
|
|
|
|
if (isNullable)
|
|
{
|
|
builder.AddAttribute(seq++, "Value", currentValue as Guid?);
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<Guid?>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
StateHasChanged();
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
builder.AddAttribute(seq++, "Value", currentValue is Guid guidVal ? guidVal : Guid.Empty);
|
|
builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create<Guid>(this, newValue =>
|
|
{
|
|
propertyInfo.SetValue(dataItem, newValue);
|
|
StateHasChanged();
|
|
}));
|
|
}
|
|
|
|
builder.AddAttribute(seq++, "ClearButtonDisplayMode", DataEditorClearButtonDisplayMode.Auto);
|
|
builder.CloseComponent();
|
|
}
|
|
|
|
private RenderFragment RenderCellContent(DxGridDataColumn column, object? value, string displayText, EditSettingsType settingsType)
|
|
{
|
|
return builder =>
|
|
{
|
|
var seq = 0;
|
|
|
|
// If column has EditSettings, render based on that
|
|
switch (settingsType)
|
|
{
|
|
case EditSettingsType.ComboBox:
|
|
// ComboBox columns show resolved display text
|
|
builder.OpenComponent<DxTextBox>(seq++);
|
|
builder.AddAttribute(seq++, "Text", displayText);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
return;
|
|
|
|
case EditSettingsType.CheckBox when value is bool boolVal:
|
|
builder.OpenComponent<DxCheckBox<bool>>(seq++);
|
|
builder.AddAttribute(seq++, "Checked", boolVal);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
return;
|
|
|
|
case EditSettingsType.DateEdit:
|
|
RenderDateEditor(builder, ref seq, value, column.DisplayFormat);
|
|
return;
|
|
|
|
case EditSettingsType.TimeEdit:
|
|
RenderTimeEditor(builder, ref seq, value, column.DisplayFormat);
|
|
return;
|
|
|
|
case EditSettingsType.SpinEdit:
|
|
builder.OpenComponent<DxTextBox>(seq++);
|
|
builder.AddAttribute(seq++, "Text", displayText);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.AddAttribute(seq++, "CssClass", "text-end");
|
|
builder.CloseComponent();
|
|
return;
|
|
|
|
case EditSettingsType.Memo:
|
|
builder.OpenComponent<DxMemo>(seq++);
|
|
builder.AddAttribute(seq++, "Text", displayText);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.AddAttribute(seq++, "Rows", 3);
|
|
builder.CloseComponent();
|
|
return;
|
|
}
|
|
|
|
// Default: render based on value type
|
|
switch (value)
|
|
{
|
|
case bool boolValue:
|
|
builder.OpenComponent<DxCheckBox<bool>>(seq++);
|
|
builder.AddAttribute(seq++, "Checked", boolValue);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
break;
|
|
|
|
case DateTime dateValue:
|
|
builder.OpenComponent<DxDateEdit<DateTime>>(seq++);
|
|
builder.AddAttribute(seq++, "Date", dateValue);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.AddAttribute(seq++, "DisplayFormat", column.DisplayFormat ?? "yyyy-MM-dd HH:mm");
|
|
builder.CloseComponent();
|
|
break;
|
|
|
|
case DateOnly dateOnlyValue:
|
|
builder.OpenComponent<DxDateEdit<DateOnly>>(seq++);
|
|
builder.AddAttribute(seq++, "Date", dateOnlyValue);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.AddAttribute(seq++, "DisplayFormat", column.DisplayFormat ?? "yyyy-MM-dd");
|
|
builder.CloseComponent();
|
|
break;
|
|
|
|
case TimeOnly timeOnlyValue:
|
|
builder.OpenComponent<DxTimeEdit<TimeOnly>>(seq++);
|
|
builder.AddAttribute(seq++, "Time", timeOnlyValue);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
break;
|
|
|
|
case TimeSpan timeSpanValue:
|
|
builder.OpenComponent<DxTimeEdit<TimeSpan>>(seq++);
|
|
builder.AddAttribute(seq++, "Time", timeSpanValue);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
break;
|
|
|
|
case decimal or double or float or int or long or short:
|
|
builder.OpenComponent<DxTextBox>(seq++);
|
|
builder.AddAttribute(seq++, "Text", displayText);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.AddAttribute(seq++, "CssClass", "text-end");
|
|
builder.CloseComponent();
|
|
break;
|
|
|
|
default:
|
|
builder.OpenComponent<DxTextBox>(seq++);
|
|
builder.AddAttribute(seq++, "Text", displayText);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
break;
|
|
}
|
|
};
|
|
}
|
|
|
|
private void RenderDateEditor(RenderTreeBuilder builder, ref int seq, object? value, string? displayFormat)
|
|
{
|
|
switch (value)
|
|
{
|
|
case DateTime dateTime:
|
|
builder.OpenComponent<DxDateEdit<DateTime>>(seq++);
|
|
builder.AddAttribute(seq++, "Date", dateTime);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.AddAttribute(seq++, "DisplayFormat", displayFormat ?? "yyyy-MM-dd HH:mm");
|
|
builder.CloseComponent();
|
|
break;
|
|
case DateOnly dateOnly:
|
|
builder.OpenComponent<DxDateEdit<DateOnly>>(seq++);
|
|
builder.AddAttribute(seq++, "Date", dateOnly);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.AddAttribute(seq++, "DisplayFormat", displayFormat ?? "yyyy-MM-dd");
|
|
builder.CloseComponent();
|
|
break;
|
|
case DateTimeOffset dateTimeOffset:
|
|
builder.OpenComponent<DxDateEdit<DateTimeOffset>>(seq++);
|
|
builder.AddAttribute(seq++, "Date", dateTimeOffset);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.AddAttribute(seq++, "DisplayFormat", displayFormat ?? "yyyy-MM-dd HH:mm");
|
|
builder.CloseComponent();
|
|
break;
|
|
default:
|
|
builder.OpenComponent<DxTextBox>(seq++);
|
|
builder.AddAttribute(seq++, "Text", value?.ToString() ?? string.Empty);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void RenderTimeEditor(RenderTreeBuilder builder, ref int seq, object? value, string? displayFormat)
|
|
{
|
|
switch (value)
|
|
{
|
|
case TimeOnly timeOnly:
|
|
builder.OpenComponent<DxTimeEdit<TimeOnly>>(seq++);
|
|
builder.AddAttribute(seq++, "Time", timeOnly);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
break;
|
|
case TimeSpan timeSpan:
|
|
builder.OpenComponent<DxTimeEdit<TimeSpan>>(seq++);
|
|
builder.AddAttribute(seq++, "Time", timeSpan);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
break;
|
|
case DateTime dateTime:
|
|
builder.OpenComponent<DxTimeEdit<DateTime>>(seq++);
|
|
builder.AddAttribute(seq++, "Time", dateTime);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
break;
|
|
default:
|
|
builder.OpenComponent<DxTextBox>(seq++);
|
|
builder.AddAttribute(seq++, "Text", value?.ToString() ?? string.Empty);
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
break;
|
|
}
|
|
}
|
|
}
|