The protected bool bandEditorExpanded, which tracked the expansion state of the band editor, has been removed from BandGridBase<TItem> as it is no longer used. This helps clean up unused state from the component.
214 lines
8.0 KiB
C#
214 lines
8.0 KiB
C#
using DbFirst.BlazorWebApp.Models.Grid;
|
|
using DbFirst.BlazorWebApp.Services;
|
|
using DevExpress.Blazor;
|
|
using Microsoft.AspNetCore.Components;
|
|
using Microsoft.AspNetCore.Components.Rendering;
|
|
|
|
namespace DbFirst.BlazorWebApp.Components;
|
|
|
|
public abstract class BandGridBase<TItem> : ComponentBase
|
|
{
|
|
[Inject] protected BandLayoutService BandLayoutService { get; set; } = default!;
|
|
|
|
// --- Abstract: jedes Grid definiert diese selbst ---
|
|
protected abstract string LayoutKey { get; }
|
|
protected abstract List<ColumnDefinition> ColumnDefinitions { get; }
|
|
|
|
// --- Band-Layout Felder ---
|
|
protected BandLayout bandLayout = new();
|
|
protected Dictionary<string, string> columnBandAssignments = new();
|
|
protected List<BandOption> bandOptions = new();
|
|
protected Dictionary<string, ColumnDefinition> columnLookup = new();
|
|
protected string? layoutUser;
|
|
protected bool gridLayoutApplied;
|
|
protected IGrid? gridRef;
|
|
|
|
// --- SizeMode ---
|
|
protected SizeMode _sizeMode = SizeMode.Medium;
|
|
protected static readonly List<SizeMode> _sizeModes = Enum.GetValues<SizeMode>().ToList();
|
|
|
|
private const string LayoutType = "GRID_BANDS";
|
|
|
|
// --- Lifecycle ---
|
|
protected async Task InitializeBandLayoutAsync()
|
|
{
|
|
columnLookup = ColumnDefinitions.ToDictionary(c => c.FieldName, StringComparer.OrdinalIgnoreCase);
|
|
layoutUser = await BandLayoutService.EnsureLayoutUserAsync();
|
|
bandLayout = await BandLayoutService.LoadBandLayoutAsync(LayoutType, LayoutKey, layoutUser, columnLookup);
|
|
columnBandAssignments = BandLayoutService.BuildAssignmentsFromLayout(bandLayout);
|
|
ApplyColumnLayoutFromStorage();
|
|
_sizeMode = bandLayout.SizeMode;
|
|
UpdateBandOptions();
|
|
}
|
|
|
|
protected async Task ApplyGridLayoutAfterRenderAsync()
|
|
{
|
|
if (!gridLayoutApplied && gridRef != null && bandLayout.GridLayout != null)
|
|
{
|
|
gridRef.LoadLayout(bandLayout.GridLayout);
|
|
gridLayoutApplied = true;
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
}
|
|
|
|
// --- Layout speichern / zurücksetzen ---
|
|
protected async Task SaveLayoutAsync()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(layoutUser)) return;
|
|
CaptureColumnLayoutFromGrid();
|
|
await BandLayoutService.SaveBandLayoutAsync(LayoutType, LayoutKey, layoutUser, bandLayout);
|
|
}
|
|
|
|
protected async Task ResetLayoutAsync()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(layoutUser)) return;
|
|
await BandLayoutService.ResetBandLayoutAsync(LayoutType, LayoutKey, layoutUser);
|
|
bandLayout = new BandLayout();
|
|
columnBandAssignments.Clear();
|
|
UpdateBandOptions();
|
|
foreach (var column in ColumnDefinitions)
|
|
column.Width = null;
|
|
columnLookup = ColumnDefinitions.ToDictionary(c => c.FieldName, StringComparer.OrdinalIgnoreCase);
|
|
_sizeMode = SizeMode.Medium;
|
|
gridRef?.LoadLayout(new GridPersistentLayout());
|
|
gridLayoutApplied = false;
|
|
}
|
|
|
|
private void CaptureColumnLayoutFromGrid()
|
|
{
|
|
if (gridRef == null) return;
|
|
var layout = gridRef.SaveLayout();
|
|
bandLayout.GridLayout = layout;
|
|
bandLayout.SizeMode = _sizeMode;
|
|
var orderedColumns = layout.Columns
|
|
.Where(c => !string.IsNullOrWhiteSpace(c.FieldName))
|
|
.OrderBy(c => c.VisibleIndex)
|
|
.ToList();
|
|
bandLayout.ColumnOrder = orderedColumns.Select(c => c.FieldName).ToList();
|
|
bandLayout.ColumnWidths = orderedColumns
|
|
.Where(c => !string.IsNullOrWhiteSpace(c.Width))
|
|
.ToDictionary(c => c.FieldName, c => c.Width, StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
private void ApplyColumnLayoutFromStorage()
|
|
{
|
|
foreach (var column in ColumnDefinitions)
|
|
{
|
|
if (bandLayout.ColumnWidths.TryGetValue(column.FieldName, out var width) && !string.IsNullOrWhiteSpace(width))
|
|
column.Width = width;
|
|
}
|
|
columnLookup = ColumnDefinitions.ToDictionary(c => c.FieldName, StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
// --- Band-Methoden ---
|
|
protected bool CanSaveBandLayout => !string.IsNullOrWhiteSpace(layoutUser);
|
|
|
|
protected void AddBand()
|
|
{
|
|
bandLayout.Bands.Add(new BandDefinition { Id = Guid.NewGuid().ToString("N"), Caption = "Band" });
|
|
UpdateBandOptions();
|
|
}
|
|
|
|
protected void RemoveBand(BandDefinition band)
|
|
{
|
|
bandLayout.Bands.Remove(band);
|
|
foreach (var key in columnBandAssignments.Where(p => p.Value == band.Id).Select(p => p.Key).ToList())
|
|
columnBandAssignments.Remove(key);
|
|
UpdateBandOptions();
|
|
SyncBandsFromAssignments();
|
|
}
|
|
|
|
protected void UpdateBandCaption(BandDefinition band, string value)
|
|
{
|
|
band.Caption = value;
|
|
UpdateBandOptions();
|
|
}
|
|
|
|
protected void UpdateColumnBand(string fieldName, string? bandId)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(bandId))
|
|
columnBandAssignments.Remove(fieldName);
|
|
else
|
|
columnBandAssignments[fieldName] = bandId;
|
|
SyncBandsFromAssignments();
|
|
}
|
|
|
|
protected string GetColumnBand(string fieldName)
|
|
=> columnBandAssignments.TryGetValue(fieldName, out var bandId) ? bandId : string.Empty;
|
|
|
|
protected void SyncBandsFromAssignments()
|
|
{
|
|
foreach (var band in bandLayout.Bands)
|
|
{
|
|
band.Columns = ColumnDefinitions
|
|
.Where(c => columnBandAssignments.TryGetValue(c.FieldName, out var id) && id == band.Id)
|
|
.Select(c => c.FieldName)
|
|
.ToList();
|
|
}
|
|
StateHasChanged();
|
|
}
|
|
|
|
protected void UpdateBandOptions()
|
|
{
|
|
bandOptions = new List<BandOption> { new() { Id = string.Empty, Caption = "Ohne Band" } };
|
|
bandOptions.AddRange(bandLayout.Bands.Select(b => new BandOption { Id = b.Id, Caption = b.Caption }));
|
|
}
|
|
|
|
// --- SizeMode ---
|
|
protected string FormatSizeText(SizeMode size) => size switch
|
|
{
|
|
SizeMode.Small => "Klein",
|
|
SizeMode.Medium => "Mittel",
|
|
SizeMode.Large => "Groß",
|
|
_ => size.ToString()
|
|
};
|
|
|
|
protected void OnSizeChange(DropDownButtonItemClickEventArgs args)
|
|
{
|
|
_sizeMode = Enum.Parse<SizeMode>(args.ItemInfo.Id);
|
|
}
|
|
|
|
// --- RenderColumns / BuildDataColumn ---
|
|
protected RenderFragment RenderColumns() => builder =>
|
|
{
|
|
var seq = 0;
|
|
builder.OpenComponent<DxGridCommandColumn>(seq++);
|
|
builder.AddAttribute(seq++, "Width", "120px");
|
|
builder.CloseComponent();
|
|
|
|
var grouped = bandLayout.Bands.SelectMany(b => b.Columns).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
|
foreach (var column in ColumnDefinitions.Where(c => !grouped.Contains(c.FieldName)))
|
|
BuildDataColumn(builder, ref seq, column);
|
|
|
|
foreach (var band in bandLayout.Bands)
|
|
{
|
|
if (band.Columns.Count == 0) continue;
|
|
builder.OpenComponent<DxGridBandColumn>(seq++);
|
|
builder.AddAttribute(seq++, "Caption", band.Caption);
|
|
builder.AddAttribute(seq++, "Columns", (RenderFragment)(bandBuilder =>
|
|
{
|
|
var bandSeq = 0;
|
|
foreach (var columnName in band.Columns)
|
|
{
|
|
if (columnLookup.TryGetValue(columnName, out var column))
|
|
BuildDataColumn(bandBuilder, ref bandSeq, column);
|
|
}
|
|
}));
|
|
builder.CloseComponent();
|
|
}
|
|
};
|
|
|
|
protected void BuildDataColumn(RenderTreeBuilder builder, ref int seq, ColumnDefinition column)
|
|
{
|
|
builder.OpenComponent<DxGridDataColumn>(seq++);
|
|
builder.AddAttribute(seq++, "FieldName", column.FieldName);
|
|
builder.AddAttribute(seq++, "Caption", column.Caption);
|
|
if (!string.IsNullOrWhiteSpace(column.Width))
|
|
builder.AddAttribute(seq++, "Width", column.Width);
|
|
if (!string.IsNullOrWhiteSpace(column.DisplayFormat))
|
|
builder.AddAttribute(seq++, "DisplayFormat", column.DisplayFormat);
|
|
if (column.ReadOnly)
|
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
|
builder.CloseComponent();
|
|
}
|
|
} |