IPaneHostSurface interface Core

What a host must provide so the grid's standard panes can run on it: put a content on screen, measure a string, and reach into the grid's live state. No window, control or framework type appears in it.

A host may satisfy IPaneHostSurface.ShowPane however it likes: drawn into the grid frame (the in-bounds OverlayManager) or as a real top-level surface.

public interface IPaneHostSurface
Namespace
ArionUI.Presentation.Overlay
Package
ArionUI.Presentation · dotnet add package ArionUI.Presentation --prerelease

Properties

CanUserGroupColumns

bool CanUserGroupColumns { get; }

Whether end-user gestures may group columns — same back-door rule as IPaneHostSurface.CanUserSortColumns.

CanUserSortColumns

bool CanUserSortColumns { get; }

Whether end-user gestures may sort columns. The context menu must build from this too, or a disabled switch has a back door through "Sort ascending".

Engine

ArionEngine Engine { get; }

The engine, for reading the item a pane was opened over.

Input

InteractionController Input { get; }

The live edit/selection layer — the pickers commit through it so a typed value and a picked one take the exact same path.

MainView

ArionView MainView { get; }

The view the panes act on — used to re-bucket grouping after a commit.

PanePointer

LogPoint PanePointer { get; }

Where a pane opens "at the pointer", IN THIS HOST'S pane coordinates. Only the host knows that space: Avalonia's overlay layer sits outside the zoom transform and must re-multiply by it, WPF draws into the grid frame and does not. The grid asks rather than computes, so it can place a pane without knowing which of the two it is talking to.

Template

ITemplate Template { get; }

The template, for per-column presentation (drop-down style, date format).

Theme

ArionTheme Theme { get; }

The theme owned by this grid instance. Pane content can be constructed outside a render pass and must therefore not read the ambient current theme.

Today

DateTime Today { get; }

What this grid calls TODAY — the date the calendar rings and its "today" button jump to. Defaults to the machine's.

Here rather than read from DateTime.Today where it is drawn, for two reasons. A demo or a report that shows a fixed day needs the ring to sit on THAT day, not on whatever day the reader happens to open it. And the ring could not be proven at all: a probe would have had to assert against the clock it was running on, which is a probe that agrees with any implementation.

Methods

CellPanePosition

LogPoint CellPanePosition(int itemIndex, int elementId);

Same space, but anchored to a CELL — a menu opened from the keyboard hangs off the focused cell, never off a pointer that has not moved in a while. Falls back to IPaneHostSurface.PanePointer when the cell cannot be located.

ColumnWidthAt

double ColumnWidthAt(int elementId);

Current on-screen width of a column, so a classic combo can match its cell.

IsElementPinned

bool IsElementPinned(int elementId);

IsElementPinnedRight

bool IsElementPinnedRight(int elementId);

Is the column pinned at the right edge?

MeasureText

double MeasureText(string text, TextStyle style);

The host's REAL glyph measurer — panes size themselves from it rather than estimating characters, so a menu is exactly as wide as its widest entry.

OpenSubmenu

void OpenSubmenu(object ownerKey, IOverlayContent content, LogRect anchorRect, OverlayPlacement placement);

Push a submenu for a pane's own control (a drop-down inside a form pane), anchored to anchorRect in the parent pane's coordinates. ownerKey is the trigger identity that makes a second click on the same row TOGGLE the submenu shut instead of reopening it.

RefreshView

void RefreshView();

Re-solve and repaint after a pane changed LAYOUT-affecting state (the header menu's "compact group rows" toggle changes a template width). A plain invalidate would not do: the column solve has to run again.

ShowPane

void ShowPane(IOverlayContent content, LogPoint at, bool stacked = false, Action? onClosed = null, string? sizeMemoryKey = null, object? ownerKey = null);

Put content on screen at at (grid-local logical coords).

Parameters

stacked

Open ABOVE the current pane (a submenu) instead of replacing it.

onClosed

Runs when the pane closes, however it closes. The cell dropdowns need it: their ▾ stays lit while the picker is up, so losing this hook leaves a ▾ lit forever.

sizeMemoryKey

Non-null makes the pane resizable and remembers the size the user dragged under this key.

ownerKey

Stable identity of the TRIGGER (a chip, a button). With a key, the pane TOGGLES: the press that reopens it from the same trigger finds the stack just closed it (press-outside) and leaves it closed instead of reopening.

ShowValueFilter

void ShowValueFilter(IGridViewOps grid, int elementId, LogPoint? at = default);

Open the value-filter dialog for a column. Its own method because the host owns the anchor: with no point it hangs off that column's filter cell, never off the funnel that opened it.

ToggleElementPin

void ToggleElementPin(int elementId);

ToggleElementPinRight

void ToggleElementPinRight(int elementId);

Pin the column at the right edge, or unpin it from there.