@using DevExpress.Blazor @using Microsoft.AspNetCore.Components.Rendering @using System.Reflection
@* Header *@ @if (HeaderTemplate != null) { @HeaderTemplate(GetActiveDataItem()) } else {
@(_currentGrid?.Caption ?? "")
} @* Toolbar *@ @if (_currentGrid != null) {
} @* Content *@
@if (GetActiveDataItem() != null && _currentGrid != null) { @* Before Columns *@ @if (BeforeColumnsTemplate != null) { @BeforeColumnsTemplate(GetActiveDataItem()) } @* Columns *@ @if (ColumnsTemplate != null) { @ColumnsTemplate(GetActiveDataItem()) } else { @RenderDefaultColumns() } @* After Columns *@ @if (AfterColumnsTemplate != null) { @AfterColumnsTemplate(GetActiveDataItem()) } } else {

Válasszon ki egy sort az adatok megtekintéséhez

}
@* Footer *@ @if (FooterTemplate != null) { @FooterTemplate(GetActiveDataItem()) }
@code { /// /// Custom header template. Receives the current data item. /// [Parameter] public RenderFragment? HeaderTemplate { get; set; } /// /// Content to render before the columns. /// [Parameter] public RenderFragment? BeforeColumnsTemplate { get; set; } /// /// Custom columns template. If not set, columns are auto-generated. /// [Parameter] public RenderFragment? ColumnsTemplate { get; set; } /// /// Content to render after the columns. /// [Parameter] public RenderFragment? AfterColumnsTemplate { get; set; } /// /// Custom footer template. /// [Parameter] public RenderFragment? FooterTemplate { get; set; } private string GetColumnCountClass() { if (FixedColumnCount.HasValue) { return FixedColumnCount.Value switch { 1 => "mg-columns-1", 2 => "mg-columns-2", 3 => "mg-columns-3", 4 => "mg-columns-4", _ => "" }; } return ""; } private string GetBreakpointStyles() { return $"--mg-bp-2col: {TwoColumnBreakpoint}px; --mg-bp-3col: {ThreeColumnBreakpoint}px; --mg-bp-4col: {FourColumnBreakpoint}px;"; } private RenderFragment RenderDefaultColumns() => builder => { var dataItem = GetActiveDataItem()!; var dataItemType = dataItem.GetType(); var seq = 0; builder.OpenElement(seq++, "div"); builder.AddAttribute(seq++, "class", "mg-info-panel-grid"); foreach (var column in GetVisibleColumns()) { var displayText = GetDisplayTextFromGrid(column); var value = GetCellValue(column); var settingsType = GetEditSettingsType(column); var isReadOnly = !_isEditMode || column.ReadOnly; builder.OpenElement(seq++, "div"); builder.AddAttribute(seq++, "class", "mg-info-panel-item"); builder.OpenElement(seq++, "div"); builder.AddAttribute(seq++, "class", "dxbl-form-layout-item"); builder.OpenElement(seq++, "label"); builder.AddAttribute(seq++, "class", $"dxbl-fl-lc {GetCaptionCssClass(isReadOnly)} d-block mb-1 small"); builder.AddContent(seq++, GetColumnCaption(column)); builder.CloseElement(); builder.OpenElement(seq++, "div"); builder.AddAttribute(seq++, "class", "dxbl-fl-ec"); if (_isEditMode && !column.ReadOnly) { RenderEditableCell(column, dataItem, dataItemType, value, displayText, settingsType)(builder); } else { RenderCellContent(column, value, displayText, settingsType)(builder); } builder.CloseElement(); builder.CloseElement(); builder.CloseElement(); } builder.CloseElement(); }; private static string GetColumnCaption(DxGridDataColumn column) { return !string.IsNullOrWhiteSpace(column.Caption) ? column.Caption : column.FieldName; } private static string GetCaptionCssClass(bool isReadOnly) { return isReadOnly ? "fw-semibold" : "fw-semibold text-primary"; } private RenderFragment RenderEditableCell(DxGridDataColumn column, object dataItem, Type dataItemType, object? value, string displayText, EditSettingsType settingsType) { return builder => { var seq = 0; var fieldName = column.FieldName; var propertyInfo = dataItemType.GetProperty(fieldName); if (propertyInfo == null) { RenderCellContent(column, value, displayText, settingsType)(builder); return; } var propertyType = propertyInfo.PropertyType; var underlyingType = Nullable.GetUnderlyingType(propertyType) ?? propertyType; // ComboBox if (settingsType == EditSettingsType.ComboBox) { var comboSettings = GetEditSettings(column.FieldName) as DxComboBoxSettings; if (comboSettings != null) { RenderComboBoxEditor(builder, ref seq, dataItem, propertyInfo, comboSettings); return; } } // Render based on 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(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) RenderMemoEditor(builder, ref seq, dataItem, propertyInfo); else RenderTextBoxEditor(builder, ref seq, dataItem, propertyInfo); }; } private void RenderCheckBoxEditor(RenderTreeBuilder builder, ref int seq, object dataItem, PropertyInfo propertyInfo) { var currentValue = (bool)(propertyInfo.GetValue(dataItem) ?? false); builder.OpenComponent>(seq++); builder.AddAttribute(seq++, "Checked", currentValue); builder.AddAttribute(seq++, "CheckedChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); builder.CloseComponent(); } private void RenderDateTimeEditor(RenderTreeBuilder builder, ref int seq, object dataItem, PropertyInfo propertyInfo, string? displayFormat) { var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null; var currentValue = propertyInfo.GetValue(dataItem); if (isNullable) { builder.OpenComponent>(seq++); builder.AddAttribute(seq++, "Date", (DateTime?)currentValue); builder.AddAttribute(seq++, "DateChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); } else { builder.OpenComponent>(seq++); builder.AddAttribute(seq++, "Date", (DateTime)(currentValue ?? DateTime.MinValue)); builder.AddAttribute(seq++, "DateChanged", EventCallback.Factory.Create(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, object dataItem, PropertyInfo propertyInfo, string? displayFormat) { var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null; var currentValue = propertyInfo.GetValue(dataItem); if (isNullable) { builder.OpenComponent>(seq++); builder.AddAttribute(seq++, "Date", (DateOnly?)currentValue); builder.AddAttribute(seq++, "DateChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); } else { builder.OpenComponent>(seq++); builder.AddAttribute(seq++, "Date", (DateOnly)(currentValue ?? DateOnly.MinValue)); builder.AddAttribute(seq++, "DateChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); } builder.AddAttribute(seq++, "DisplayFormat", displayFormat ?? "yyyy-MM-dd"); builder.CloseComponent(); } private void RenderSpinIntEditor(RenderTreeBuilder builder, ref int seq, object dataItem, PropertyInfo propertyInfo) { var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null; var currentValue = propertyInfo.GetValue(dataItem); if (isNullable) { builder.OpenComponent>(seq++); builder.AddAttribute(seq++, "Value", (int?)currentValue); builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); } else { builder.OpenComponent>(seq++); builder.AddAttribute(seq++, "Value", (int)(currentValue ?? 0)); builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); } builder.CloseComponent(); } private void RenderSpinDecimalEditor(RenderTreeBuilder builder, ref int seq, object dataItem, PropertyInfo propertyInfo) { var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null; var currentValue = propertyInfo.GetValue(dataItem); if (isNullable) { builder.OpenComponent>(seq++); builder.AddAttribute(seq++, "Value", (decimal?)currentValue); builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); } else { builder.OpenComponent>(seq++); builder.AddAttribute(seq++, "Value", (decimal)(currentValue ?? 0m)); builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); } builder.CloseComponent(); } private void RenderSpinDoubleEditor(RenderTreeBuilder builder, ref int seq, object dataItem, PropertyInfo propertyInfo) { var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null; var currentValue = propertyInfo.GetValue(dataItem); if (isNullable) { builder.OpenComponent>(seq++); builder.AddAttribute(seq++, "Value", (double?)currentValue); builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); } else { builder.OpenComponent>(seq++); builder.AddAttribute(seq++, "Value", (double)(currentValue ?? 0d)); builder.AddAttribute(seq++, "ValueChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); } builder.CloseComponent(); } private void RenderTextBoxEditor(RenderTreeBuilder builder, ref int seq, object dataItem, PropertyInfo propertyInfo) { var currentValue = propertyInfo.GetValue(dataItem)?.ToString() ?? string.Empty; builder.OpenComponent(seq++); builder.AddAttribute(seq++, "Text", currentValue); builder.AddAttribute(seq++, "TextChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); builder.CloseComponent(); } private void RenderMemoEditor(RenderTreeBuilder builder, ref int seq, object dataItem, PropertyInfo propertyInfo) { var currentValue = propertyInfo.GetValue(dataItem)?.ToString() ?? string.Empty; builder.OpenComponent(seq++); builder.AddAttribute(seq++, "Text", currentValue); builder.AddAttribute(seq++, "TextChanged", EventCallback.Factory.Create(this, newValue => { propertyInfo.SetValue(dataItem, newValue); InvokeAsync(StateHasChanged); })); builder.AddAttribute(seq++, "Rows", 3); builder.CloseComponent(); } private void RenderComboBoxEditor(RenderTreeBuilder builder, ref int seq, object dataItem, PropertyInfo propertyInfo, DxComboBoxSettings settings) { var currentValue = propertyInfo.GetValue(dataItem); var propertyType = propertyInfo.PropertyType; var underlyingType = Nullable.GetUnderlyingType(propertyType) ?? propertyType; var dataType = settings.Data?.GetType(); var itemType = typeof(object); if (dataType?.IsGenericType == true) { var genericArgs = dataType.GetGenericArguments(); if (genericArgs.Length > 0) itemType = genericArgs[0]; } 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 { var displayText = ResolveComboBoxDisplayText(settings, currentValue ?? new object()) ?? currentValue?.ToString() ?? string.Empty; builder.OpenComponent(seq++); builder.AddAttribute(seq++, "Text", displayText); builder.AddAttribute(seq++, "ReadOnly", true); builder.CloseComponent(); } } private void RenderComboBoxInt(RenderTreeBuilder builder, ref int seq, object dataItem, PropertyInfo propertyInfo, DxComboBoxSettings settings, Type itemType, object? currentValue) { var isNullable = Nullable.GetUnderlyingType(propertyInfo.PropertyType) != null; 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(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(this, newValue => { propertyInfo.SetValue(dataItem, newValue); StateHasChanged(); })); } builder.AddAttribute(seq++, "ClearButtonDisplayMode", DataEditorClearButtonDisplayMode.Auto); builder.CloseComponent(); } private void RenderComboBoxLong(RenderTreeBuilder builder, ref int seq, object 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(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(this, newValue => { propertyInfo.SetValue(dataItem, newValue); StateHasChanged(); })); } builder.AddAttribute(seq++, "ClearButtonDisplayMode", DataEditorClearButtonDisplayMode.Auto); builder.CloseComponent(); } private void RenderComboBoxGuid(RenderTreeBuilder builder, ref int seq, object 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(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(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; // View mode: simple span display with DevExpress theme styling builder.OpenElement(seq++, "span"); builder.AddAttribute(seq++, "class", GetViewModeCssClass(value, settingsType)); builder.AddAttribute(seq++, "title", displayText); // Special handling for boolean - show checkbox icon if (value is bool boolValue) { builder.OpenElement(seq++, "span"); builder.AddAttribute(seq++, "class", boolValue ? "dx-icon dx-icon-check text-success" : "dx-icon dx-icon-close text-muted"); builder.CloseElement(); } else { builder.AddContent(seq++, displayText); } builder.CloseElement(); }; } private static string GetViewModeCssClass(object? value, EditSettingsType settingsType) { var baseCss = "mg-info-panel-value text-body"; return value switch { bool => $"{baseCss} mg-info-panel-value-bool", decimal or double or float or int or long or short => $"{baseCss} mg-info-panel-value-numeric", DateTime or DateOnly or TimeOnly => $"{baseCss} mg-info-panel-value-date", _ => baseCss }; } }