Skip to content

feature - Improve navigation#323

Merged
erikdarlingdata merged 4 commits into
erikdarlingdata:devfrom
ClaudioESSilva:ImproveNavigation
May 10, 2026
Merged

feature - Improve navigation#323
erikdarlingdata merged 4 commits into
erikdarlingdata:devfrom
ClaudioESSilva:ImproveNavigation

Conversation

@ClaudioESSilva
Copy link
Copy Markdown
Contributor

What does this PR do?

Implements #322

Which component(s) does this affect?

  • Desktop App (PlanViewer.App)
  • Core Library (PlanViewer.Core)
  • CLI Tool (PlanViewer.Cli)
  • SSMS Extension (PlanViewer.Ssms)
  • Tests
  • Documentation

How was this tested?

Tab navigation

  1. Open multiple tabs with "CTRL + N"
  2. Use "CTRL + TAB" and "CTRL + SHIFT + TAB" to navigate through the tabs.

Close tabs with mouse wheel click

  1. Open multiple tabs with "CTRL + N"
  2. Use the mouse wheel to click on the tab text and see them closing.

Expand/collapse grouped rows on Query Store grid

  1. Open query store
  2. Double-click on a row to expand.
  3. Double-click again to collapse.

Checklist

  • I have read the contributing guide
  • My code builds with zero warnings (dotnet build -c Debug)
  • All tests pass (dotnet test)
  • I have not introduced any hardcoded credentials or server names

@erikdarlingdata
Copy link
Copy Markdown
Owner

Nice — keyboard nav and middle-click close are great quality-of-life. One real bug and one nit.

Should-fix

  • Controls/QueryStoreGridControl.axaml.cs ResultsGrid_DoubleTappedDoubleTapped on a DataGrid is a routed event that fires for taps anywhere inside the grid, including column headers, the empty area below the last row, and inner cell controls. Three problems:

    1. Double-clicking a column header (e.g. to auto-resize) toggles expansion of whichever row is currently selected.
    2. Double-clicking the chevron Button in the row produces a triple toggle: Click→Click on the button (toggles twice, ending in original state) plus the bubbled DoubleTapped on the grid (toggles once more) — net result is the opposite of what the user expects.
    3. Empty-area double-clicks below the last row also fire if a row is selected.

    Recommended fix: filter e.Source to require a DataGridRow ancestor and reject Button ancestors before toggling.

    private void ResultsGrid_DoubleTapped(object? sender, TappedEventArgs e)
    {
        if (e.Source is not Visual v) return;
        if (v.FindAncestorOfType<Button>() != null) return;
        if (v.FindAncestorOfType<DataGridRow>() == null) return;
        if (ResultsGrid.SelectedItem is not QueryStoreRow row) return;
        if (!row.HasChildren) return;
        ToggleRowExpansion(row);
    }

Nit

  • MainWindow.axaml.cs middle-click on tab headerStackPanel with no background doesn't receive pointer events on the gap between its children. Hits register on headerText (TextBlock) and closeBtn (Button), and they bubble to the StackPanel handler, so it works in practice. To be defensive, set Background=\"Transparent\" on the header StackPanel so the whole rectangle is hit-testable.

Clean

  • Ctrl+Tab / Ctrl+Shift+Tab modifier matching is correct — the strict-equality == in the existing block doesn't trip because Ctrl+Shift+Tab is split into its own else if against Control | Shift. Wrap-around math handles 0/1 tabs and SelectedIndex == -1 correctly.
  • The ExpandRow_ClickToggleRowExpansion extraction is a clean refactor.

Copy link
Copy Markdown
Owner

@erikdarlingdata erikdarlingdata left a comment

Choose a reason for hiding this comment

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

Both fixes look great — the DoubleTapped guards and the transparent header background are exactly the right shape. Thanks for the quick turnaround! LGTM.

@erikdarlingdata erikdarlingdata merged commit 801f257 into erikdarlingdata:dev May 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants