Fix/query store grid usability#18
Conversation
erikdarlingdata
left a comment
There was a problem hiding this comment.
Code Review
Good contribution — numeric sorting, column filtering, reordering, and horizontal scroll all add real value. Code is clean and well-organized. A few things to address before merge.
🔴 Required Fix: Cross-Platform Icon Font
The filter button uses Segoe Fluent Icons,Segoe MDL2 Assets for the filter icon (\uE71C) and active indicator (\uE16E). This font only exists on Windows. Performance Studio ships for linux-x64, osx-x64, and osx-arm64 — those platforms will show empty squares or nothing.
PerformanceMonitor Lite gets away with Segoe MDL2 because it's WPF (Windows-only). Performance Studio is Avalonia (cross-platform).
What to change:
In QueryStoreGridControl.axaml.cs, method SetColumnFilterButton(), replace:
Text = "\uE71C",
FontFamily = new Avalonia.Media.FontFamily("Segoe Fluent Icons,Segoe MDL2 Assets"),with a platform-safe Unicode character (no FontFamily needed):
Text = "▽",In UpdateFilterButtonStyles(), replace:
tb.Text = hasFilter ? "\uE16E" : "\uE71C";with:
tb.Text = hasFilter ? "▼" : "▽";The gold color (#FFD700) for active filters is fine — that's just a foreground color and works everywhere.
🔴 Required Fix: LoadSelectedPlans_Click Should Use _filteredRows
SelectAll_Click and SelectNone_Click were correctly updated to operate on _filteredRows, but LoadSelectedPlans_Click still iterates _rows:
// Current (inconsistent):
var selected = _rows.Where(r => r.IsSelected).Select(r => r.Plan).ToList();
// Should be:
var selected = _filteredRows.Where(r => r.IsSelected).Select(r => r.Plan).ToList();Without this, hidden-but-checked rows get loaded when a user checks rows, filters to hide some, then clicks "Load Selected".
🟡 Suggested: Query Text Column Width
Changed from Width="*" (fills remaining space) to Width="300" MinWidth="150". This means the grid won't fill available width on wide monitors — there will be dead space to the right.
Suggestion: In QueryStoreGridControl.axaml, use Width="*" with MinWidth="300" instead, so the column still stretches but has a guaranteed minimum:
<DataGridTemplateColumn Header="Query Text" Width="*" MinWidth="300">🟡 Suggested: Remove Dead Code
ColumnFilterState.GetOperatorDisplayName() is defined but never called anywhere. The same display strings already exist in the Operators tuple array in ColumnFilterPopup.cs. Remove the unused method from ColumnFilterState.cs (lines 55-69) to keep things clean.
✅ What's Good
- SortMemberPath properties — Clean pattern with 16 numeric sort properties exposing raw values while display properties show formatted strings. Exactly right.
- Unit conversions in NumericAccessors — Filter values match display units (µs→ms for CPU/Duration, pages→MB for memory). Thoughtful.
- Column index offset — Correctly starts at
cols[1], skipping the checkbox column. - Filter popup — Reuses app theme resources (
BackgroundDarkBrush,BorderBrush,AppButton). Enter/Escape keyboard shortcuts work naturally. - Status text — Shows "X / Y plans (filtered)" when filters are active. Nice touch.
- Filter state UX — Active filters change icon color to gold with tooltip showing the expression. Clear signal.
Summary
| Item | Severity | File(s) |
|---|---|---|
| Replace Segoe icon font with Unicode chars | 🔴 Required | QueryStoreGridControl.axaml.cs |
LoadSelectedPlans_Click use _filteredRows |
🔴 Required | QueryStoreGridControl.axaml.cs |
Query Text Width="*" MinWidth="300" |
🟡 Suggested | QueryStoreGridControl.axaml |
Remove unused GetOperatorDisplayName |
🟡 Suggested | ColumnFilterState.cs |
|
@erikdarlingdata on the
This will make the grid lose its horizontal scroll bar, and worse than that, will create this problem on "smaller" screens.
So if you agree, we should keep the 300 on the Width and then people can resize any column and use the horizontal scroll bar if needed. All other 3 fixed. |
erikdarlingdata
left a comment
There was a problem hiding this comment.
All four items addressed. Cross-platform icons, _filteredRows fix, dead code removed, and Width=300 rationale makes sense — keeping it. LGTM.

What does this PR do?
Fixes #14 and #15
Implements #16 and #17
Which component(s) does this affect?
How was this tested?
Open the "Query Store" and navigate in the grid.
Before
After
Checklist
dotnet build -c Debug)dotnet test)