mirror of
https://github.com/radzenhq/radzen-blazor.git
synced 2026-07-08 18:16:08 +00:00
Extract HeaderBase for ColumnHeader and RowHeader
Both components had ~100 lines of identical code for selection state tracking, event subscription, and disposal. Extract shared logic into HeaderBase with four one-liner axis overrides per subclass.
This commit is contained in:
committed by
Vladimir Enchev
parent
b1cbf3ef4a
commit
c349b62d46
@@ -1,6 +1,6 @@
|
||||
@using Radzen.Documents.Spreadsheet
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@inherits CellBase
|
||||
@inherits HeaderBase
|
||||
<div class=@Class style=@Style data-column=@Column>
|
||||
@ColumnRef.ToString(Column)
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Radzen.Blazor.Rendering;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Radzen.Documents.Spreadsheet;
|
||||
namespace Radzen.Blazor.Spreadsheet;
|
||||
@@ -10,7 +9,7 @@ namespace Radzen.Blazor.Spreadsheet;
|
||||
/// <summary>
|
||||
/// Renders a column header in a spreadsheet.
|
||||
/// </summary>
|
||||
public partial class ColumnHeader : CellBase, IDisposable
|
||||
public partial class ColumnHeader : HeaderBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the column index of the column header.
|
||||
@@ -18,95 +17,26 @@ public partial class ColumnHeader : CellBase, IDisposable
|
||||
[Parameter]
|
||||
public int Column { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sheet that contains the column header.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Worksheet? Worksheet { get; set; }
|
||||
/// <inheritdoc/>
|
||||
protected override int Index => Column;
|
||||
|
||||
private bool active;
|
||||
private bool selected;
|
||||
/// <inheritdoc/>
|
||||
protected override string IndexParameterName => nameof(Column);
|
||||
|
||||
/// <inheritdoc/>
|
||||
[SuppressMessage("Design", "CA1062", Justification = "Base class guarantees non-null.")]
|
||||
protected override bool CheckIsActive(Selection selection) => selection.IsActive(new ColumnRef(Column));
|
||||
|
||||
/// <inheritdoc/>
|
||||
[SuppressMessage("Design", "CA1062", Justification = "Base class guarantees non-null.")]
|
||||
protected override bool CheckIsSelected(Selection selection) => selection.IsSelected(new ColumnRef(Column));
|
||||
|
||||
private string Class => ClassList.Create("rz-spreadsheet-column-header")
|
||||
.Add("rz-spreadsheet-frozen-row", FrozenState.HasFlag(FrozenState.Row))
|
||||
.Add("rz-spreadsheet-frozen-column", FrozenState.HasFlag(FrozenState.Column))
|
||||
.Add("rz-spreadsheet-header-active", active)
|
||||
.Add("rz-spreadsheet-header-selected", selected)
|
||||
.Add("rz-spreadsheet-header-active", Active)
|
||||
.Add("rz-spreadsheet-header-selected", Selected)
|
||||
.ToString();
|
||||
|
||||
private string ResizeHandleStyle => $"left: {Rect.Right.ToPx()}; top: {Rect.Top.ToPx()}; height: {Rect.Height.ToPx()};";
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
if (Worksheet != null)
|
||||
{
|
||||
Worksheet.Selection.Changed -= OnSelectionChanged;
|
||||
}
|
||||
|
||||
var didColumnChange = parameters.TryGetValue<int>(nameof(Column), out var column) && Column != column;
|
||||
|
||||
await base.SetParametersAsync(parameters);
|
||||
|
||||
if (Worksheet != null)
|
||||
{
|
||||
Worksheet.Selection.Changed += OnSelectionChanged;
|
||||
}
|
||||
|
||||
if (didColumnChange)
|
||||
{
|
||||
UpdateState();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectionChanged()
|
||||
{
|
||||
var dirty = UpdateState();
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private bool UpdateState()
|
||||
{
|
||||
var dirty = false;
|
||||
|
||||
if (Worksheet is not null)
|
||||
{
|
||||
var address = new ColumnRef(Column);
|
||||
|
||||
if (Worksheet.Selection.IsActive(address) != active)
|
||||
{
|
||||
active = !active;
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (Worksheet.Selection.IsSelected(address) != selected)
|
||||
{
|
||||
selected = !selected;
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
if (Worksheet != null)
|
||||
{
|
||||
Worksheet.Selection.Changed -= OnSelectionChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
130
Radzen.Blazor/Spreadsheet/HeaderBase.cs
Normal file
130
Radzen.Blazor/Spreadsheet/HeaderBase.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Radzen.Blazor.Rendering;
|
||||
|
||||
using Radzen.Documents.Spreadsheet;
|
||||
namespace Radzen.Blazor.Spreadsheet;
|
||||
|
||||
#nullable enable
|
||||
|
||||
/// <summary>
|
||||
/// Base class for row and column header components. Manages selection state tracking,
|
||||
/// event subscription lifecycle, and CSS class generation.
|
||||
/// Subclasses provide the axis-specific index, address creation, and CSS class name.
|
||||
/// </summary>
|
||||
public abstract class HeaderBase : CellBase, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the worksheet that contains this header.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Worksheet? Worksheet { get; set; }
|
||||
|
||||
private bool active;
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the header is in the active selection range.
|
||||
/// </summary>
|
||||
protected bool Active => active;
|
||||
|
||||
private bool selected;
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the header's entire row/column is selected.
|
||||
/// </summary>
|
||||
protected bool Selected => selected;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the axis index (row or column) for this header.
|
||||
/// </summary>
|
||||
protected abstract int Index { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter name to watch for changes (e.g. "Row" or "Column").
|
||||
/// </summary>
|
||||
protected abstract string IndexParameterName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the selection is active for this header's axis position.
|
||||
/// Called only after validating that <paramref name="selection"/> is non-null.
|
||||
/// </summary>
|
||||
protected abstract bool CheckIsActive(Selection selection);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the selection covers this header's entire row/column.
|
||||
/// Called only after validating that <paramref name="selection"/> is non-null.
|
||||
/// </summary>
|
||||
protected abstract bool CheckIsSelected(Selection selection);
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
if (Worksheet != null)
|
||||
{
|
||||
Worksheet.Selection.Changed -= OnSelectionChanged;
|
||||
}
|
||||
|
||||
var didIndexChange = parameters.TryGetValue<int>(IndexParameterName, out var index) && Index != index;
|
||||
|
||||
await base.SetParametersAsync(parameters);
|
||||
|
||||
if (Worksheet != null)
|
||||
{
|
||||
Worksheet.Selection.Changed += OnSelectionChanged;
|
||||
}
|
||||
|
||||
if (didIndexChange)
|
||||
{
|
||||
UpdateState();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectionChanged()
|
||||
{
|
||||
if (UpdateState())
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private bool UpdateState()
|
||||
{
|
||||
var dirty = false;
|
||||
|
||||
if (Worksheet is not null)
|
||||
{
|
||||
var selection = Worksheet.Selection;
|
||||
|
||||
if (CheckIsActive(selection) != active)
|
||||
{
|
||||
active = !active;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (CheckIsSelected(selection) != selected)
|
||||
{
|
||||
selected = !selected;
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
if (Worksheet != null)
|
||||
{
|
||||
Worksheet.Selection.Changed -= OnSelectionChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
@using Radzen.Documents.Spreadsheet
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@inherits CellBase
|
||||
@inherits HeaderBase
|
||||
<div class=@Class style=@Style data-row=@Row>
|
||||
@(Row + 1)
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Radzen.Blazor.Rendering;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Radzen.Documents.Spreadsheet;
|
||||
namespace Radzen.Blazor.Spreadsheet;
|
||||
@@ -12,7 +10,7 @@ namespace Radzen.Blazor.Spreadsheet;
|
||||
/// <summary>
|
||||
/// Renders a row header in a spreadsheet.
|
||||
/// </summary>
|
||||
public partial class RowHeader : CellBase, IDisposable
|
||||
public partial class RowHeader : HeaderBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the row index for the row header.
|
||||
@@ -20,93 +18,26 @@ public partial class RowHeader : CellBase, IDisposable
|
||||
[Parameter]
|
||||
public int Row { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sheet that contains the row header.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public Worksheet? Worksheet { get; set; }
|
||||
/// <inheritdoc/>
|
||||
protected override int Index => Row;
|
||||
|
||||
private bool active;
|
||||
private bool selected;
|
||||
/// <inheritdoc/>
|
||||
protected override string IndexParameterName => nameof(Row);
|
||||
|
||||
/// <inheritdoc/>
|
||||
[SuppressMessage("Design", "CA1062", Justification = "Base class guarantees non-null.")]
|
||||
protected override bool CheckIsActive(Selection selection) => selection.IsActive(new RowRef(Row));
|
||||
|
||||
/// <inheritdoc/>
|
||||
[SuppressMessage("Design", "CA1062", Justification = "Base class guarantees non-null.")]
|
||||
protected override bool CheckIsSelected(Selection selection) => selection.IsSelected(new RowRef(Row));
|
||||
|
||||
private string Class => ClassList.Create("rz-spreadsheet-row-header")
|
||||
.Add("rz-spreadsheet-frozen-row", FrozenState.HasFlag(FrozenState.Row))
|
||||
.Add("rz-spreadsheet-frozen-column", FrozenState.HasFlag(FrozenState.Column))
|
||||
.Add("rz-spreadsheet-header-active", active)
|
||||
.Add("rz-spreadsheet-header-selected", selected)
|
||||
.Add("rz-spreadsheet-header-active", Active)
|
||||
.Add("rz-spreadsheet-header-selected", Selected)
|
||||
.ToString();
|
||||
|
||||
private string ResizeHandleStyle => $"top: {Rect.Bottom.ToPx()}; left: {Rect.Left.ToPx()}; width: {Rect.Width.ToPx()};";
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
if (Worksheet != null)
|
||||
{
|
||||
Worksheet.Selection.Changed -= OnSelectionChanged;
|
||||
}
|
||||
var didRowChange = parameters.TryGetValue<int>(nameof(Row), out var row) && Row != row;
|
||||
|
||||
await base.SetParametersAsync(parameters);
|
||||
|
||||
if (Worksheet != null)
|
||||
{
|
||||
Worksheet.Selection.Changed += OnSelectionChanged;
|
||||
}
|
||||
|
||||
if (didRowChange)
|
||||
{
|
||||
UpdateState();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectionChanged()
|
||||
{
|
||||
var dirty = UpdateState();
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private bool UpdateState()
|
||||
{
|
||||
var dirty = false;
|
||||
|
||||
if (Worksheet is not null)
|
||||
{
|
||||
var address = new RowRef(Row);
|
||||
|
||||
if (Worksheet.Selection.IsActive(address) != active)
|
||||
{
|
||||
active = !active;
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (Worksheet.Selection.IsSelected(address) != selected)
|
||||
{
|
||||
selected = !selected;
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
if (Worksheet != null)
|
||||
{
|
||||
Worksheet.Selection.Changed -= OnSelectionChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user