🧱 Mason: [structural improvement] Move SearchBox KeyDown to ViewModel - #439
🧱 Mason: [structural improvement] Move SearchBox KeyDown to ViewModel#439google-labs-jules[bot] wants to merge 2 commits into
Conversation
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Code Review — PR #439: Move SearchBox KeyDown to ViewModelWhat the PR doesMoves the Overall assessmentThe intent is sound and the Blocking issues1. ViewModel references a WinUI type ( 2. 3. Indentation error in Minor issues
What's correct
@jules please address the issues noted above |
I have addressed all the issues. The |
| private bool CanExecuteSearchBoxKeyDown(Windows.System.VirtualKey key) | ||
| { | ||
| return key == Windows.System.VirtualKey.Enter || key == Windows.System.VirtualKey.Down; | ||
| } |
There was a problem hiding this comment.
Blocking — e.Handled is unconditionally set for Enter even when nothing happens.
CanExecuteSearchBoxKeyDown returns true for any Enter keypress, so Element_KeyDown in UIElementExtensions will always call command.Execute(e.Key) and then set e.Handled = true — regardless of whether SelectedItem is null. The command body is a no-op when there is no selection, but the event has already been consumed.
The original code only set e.Handled = true when an action actually ran. This regression means that pressing Enter with an empty results list (or before any item is focused) silently swallows the event instead of letting it propagate.
The fix is to make CanExecute reflect the full precondition for Enter, and notify when it changes:
| private bool CanExecuteSearchBoxKeyDown(Windows.System.VirtualKey key) | |
| { | |
| return key == Windows.System.VirtualKey.Enter || key == Windows.System.VirtualKey.Down; | |
| } | |
| private bool CanExecuteSearchBoxKeyDown(Windows.System.VirtualKey key) | |
| { | |
| return key == Windows.System.VirtualKey.Down || | |
| (key == Windows.System.VirtualKey.Enter && | |
| SelectedItem != null && | |
| LaunchAppCommand.CanExecute(SelectedItem)); | |
| } |
Then wherever SelectedItem is assigned, add:
SearchBoxKeyDownCommand.NotifyCanExecuteChanged();(Usually in the property setter or wherever the GridView selection-changed handler updates SelectedItem.)
| } | ||
| } | ||
| } | ||
| public static readonly DependencyProperty KeyDownCommandProperty = |
There was a problem hiding this comment.
Minor — missing blank line; dotnet format will fail the CI format check.
The new KeyDownCommandProperty field is placed immediately after the closing } of Element_Tapped with no blank line, while every other member group in this file is separated by a blank line.
| public static readonly DependencyProperty KeyDownCommandProperty = | |
| public static readonly DependencyProperty KeyDownCommandProperty = |
| e.Handled = true; | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Minor — double blank line left after removing SearchBox_KeyDown. The section comment // --- KEYBOARD NAVIGATION --- is now followed by two blank lines before the next section. One should be removed.
| // --- KEYBOARD NAVIGATION --- | |
| // --- WINDOW DRAGGING --- |
| else if (key == Windows.System.VirtualKey.Down) | ||
| { | ||
| GridFocusRequested?.Invoke(this, EventArgs.Empty); | ||
| } |
There was a problem hiding this comment.
Suggestion — add unit tests for the new command and event.
SearchBoxKeyDownCommand and GridFocusRequested have no test coverage (verified: MainViewModelTests.cs has zero references to either). Two straightforward cases to add:
- Pressing
VirtualKey.Enterwith a non-nullSelectedItemfiresLaunchAppCommandand does not raiseGridFocusRequested. - Pressing
VirtualKey.DownraisesGridFocusRequestedand does not attempt a launch.
Also add a case for the CanExecute regression fix above: CanExecute(Enter) should return false when SelectedItem is null, so that e.Handled is not set by the attached property.
Don't forget to link MainViewModel.cs in Launchbox.Tests/Launchbox.Tests.csproj if the file isn't already there (it is — check existing <Compile Include> entries).
Review — PR #439: Move SearchBox KeyDown to ViewModelWhat the PR doesMoves the
The overall architecture is sound. The refactor correctly isolates the concern split: the ViewModel decides what to do, the attached property / event handler decides how to do it in the View. Prior review threads — resolved in this push ✅
All three threads have been resolved. Issues still requiring attentionBlocking
Non-blocking / must-fix before merge
Minor / polish
@jules please address the issues noted above |
💡 What: Moved the SearchBox_KeyDown event handler from MainWindow.xaml.cs to a new SearchBoxKeyDownCommand in MainViewModel.
🎯 Why: Reduces technical debt by keeping business logic strictly in the ViewModel and removing UI element manipulation from code-behind.
🏗️ Architecture: Uses an attached dependency property (KeyDownCommand) to map the XAML KeyDown event to an ICommand. The ViewModel signals the View via a GridFocusRequested event to maintain a separation of concerns when requesting UI focus changes.
PR created automatically by Jules for task 16543806455729371939 started by @mikekthx