Skip to content

Add grouped spanning headers for column bands#314

Open
wieslawsoltes wants to merge 3 commits into
masterfrom
agent/issue-294-banded-group-appearance
Open

Add grouped spanning headers for column bands#314
wieslawsoltes wants to merge 3 commits into
masterfrom
agent/issue-294-banded-group-appearance

Conversation

@wieslawsoltes

@wieslawsoltes wieslawsoltes commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • add opt-in ColumnBandHeaderLayout.Grouped rendering for conventional horizontally spanning band headers
  • render shared band ancestors once across contiguous leaf columns instead of repeating the full path inside every column
  • let shallow leaves span the unused header rows while deeper branches retain their nested group levels
  • split group cells at left/right frozen-column boundaries so frozen and scrolling coordinate spaces remain correct
  • keep the existing stacked layout as the compatibility default
  • update the Column Banding sample and documentation to demonstrate the grouped layout with compiled bindings

Result

The sample band tree now renders in this structure:

|         Order         |      Merchandise      |          Financials          |
| Date | Region | Segment | Category | Product |      Revenue      |  Volume  |
|      |        |         |          |         | Sales | Profit    |  Units   |

Set the layout on the existing model:

var model = new ColumnBandModel
{
    HeaderLayout = ColumnBandHeaderLayout.Grouped
};

Stacked remains the default and preserves the previous behavior where every leaf displays its complete path.

Design

Model contract

ColumnBandHeader now carries both the complete root-to-leaf Segments path and the selected Layout. DisplaySegments keeps the existing data template reusable: stacked headers display the full path, while grouped leaf headers display only their final segment.

Changing ColumnBandModel.HeaderLayout requests the normal model refresh, so all materialized definitions receive updated header metadata without view code or reflection.

Header composition

DataGridColumnHeadersPresenter derives grouped cells from visible columns during measurement:

  • contiguous columns with the same prefix share one DataGridColumnBandHeaderCell
  • prefix comparisons include the complete ancestor path, preventing unrelated equal labels from merging
  • group cells are reused across layout passes
  • leaf headers are arranged at their depth and span all remaining rows
  • grouped cells are measured as a row, then arranged over the summed leaf-column bounds
  • scrolling cells use the same frozen-region clipping boundaries as normal headers
  • a band crossing a frozen boundary is split into separate visual cells because those sections move in different coordinate spaces

The spanning cells are non-interactive. Sorting, filtering, resizing, reordering, focus, and automation for actual columns remain on the existing leaf DataGridColumnHeader controls.

Styling

DataGridColumnBandHeaderCell has a dedicated control theme and the new DataGridColumnBandHeaderBorderThickness token in both Simple and Fluent themes. Applications can restyle the public band-cell type without replacing grid input logic.

Tests

Added headless coverage for:

  • exact horizontal spans for top-level and nested groups
  • vertical row spans for shallow leaves
  • nested Revenue → Sales/Profit geometry
  • frozen-boundary splitting
  • switching the model from stacked to grouped layout
  • Simple/Fluent theme resource and token contracts

Validation:

  • grouped-band and theme suite: 19 passed
  • complete Avalonia.Controls.DataGrid.UnitTests project: 2253 passed
  • DataGrid sample build: succeeded
  • multi-target DataGrid library build (net8.0, net10.0): succeeded
  • deterministic headless render: 540×260 PNG, 9,048 bytes, SHA-256 46b9d7b92668fae7c98e57f712b87b96eed272016961b9df62f186be59dbecfc

Fixes #294

Review hardening

Follow-up review extended grouped-header auto sizing: a spanning group header contributes its natural measured width across eligible Auto/SizeToHeader leaf columns, distributes only the unmet width, and respects each column's maximum.

Current validation: 5/5 focused banded-header tests and the complete 2,255-test unit suite pass. Review threads are resolved.

@wieslawsoltes

Copy link
Copy Markdown
Owner Author

Self-review completed. I found and fixed an edge case where adjacent, distinct band objects with identical captions were merged into one spanning header. Commit ad7ee4a carries stable band identity alongside display segments and adds a headless regression test. Focused tests passed 4/4, the full unit suite passed 2,254/2,254, all six CI checks are successful, and git diff --check is clean.

@wieslawsoltes wieslawsoltes marked this pull request as ready for review July 15, 2026 00:24

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ad7ee4adcd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Could banded columns have a more 'grouped' appearance?

1 participant