Skip to content

Commit 1c00129

Browse files
Modern UI: fix Find bar, font tuning, banner dismissal, keyboard navigation
- Rewrite FindBar: search on Enter/F3 only (no live search), fix highlight via focus-select-scroll sequence, close on Escape from output TextBox - Enable keyboard scrolling in output with IsReadOnlyCaretVisible - Mouse wheel scroll focuses output TextBox to keep highlight in sync - Keyboard scroll keys close find bar; Ctrl+F works from input TextBox - Add Find tooltip hint (Ctrl+F) on Simple view - Reduce page title font 16→15, bump annotations 11→11.5, details 11.5→12 - Clear detection banners after Download Symbols and Use Symbol Server in Simple UI - Clear all banners/glow on successful resolution
1 parent 243bc64 commit 1c00129

13 files changed

Lines changed: 90 additions & 27 deletions

Modern/Controls/FindBar.xaml.cs

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,23 @@ public void Open() {
2525
}));
2626
}
2727

28-
/// <summary>Hide the find bar and return focus to the target.</summary>
28+
/// <summary>Hide the find bar and clear state.</summary>
2929
public void Close() {
3030
Visibility = Visibility.Collapsed;
3131
_matchPositions.Clear();
3232
_currentMatchIndex = -1;
3333
MatchInfo.Text = "";
34-
_targetTextBox?.Focus();
34+
SearchBox.Text = "";
35+
}
36+
37+
private void Close_Click(object sender, RoutedEventArgs e) {
38+
Close();
39+
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Input, new Action(() => {
40+
if (_targetTextBox != null) {
41+
_targetTextBox.Focus();
42+
Keyboard.Focus(_targetTextBox);
43+
}
44+
}));
3545
}
3646

3747
public bool IsOpen => Visibility == Visibility.Visible;
@@ -53,8 +63,7 @@ private void FindMatches() {
5363
}
5464

5565
if (_matchPositions.Count > 0) {
56-
_currentMatchIndex = 0;
57-
HighlightCurrent();
66+
MatchInfo.Text = $"{_matchPositions.Count} matches";
5867
} else {
5968
MatchInfo.Text = "No matches";
6069
}
@@ -63,46 +72,57 @@ private void FindMatches() {
6372
private void HighlightCurrent() {
6473
if (_targetTextBox == null || _currentMatchIndex < 0 || _currentMatchIndex >= _matchPositions.Count) return;
6574
var pos = _matchPositions[_currentMatchIndex];
75+
var len = SearchBox.Text.Length;
76+
77+
// Focus the target briefly to make Select() work, then scroll and return focus
6678
_targetTextBox.Focus();
67-
_targetTextBox.Select(pos, SearchBox.Text.Length);
68-
// Scroll to selection by getting the character rect
69-
var rect = _targetTextBox.GetRectFromCharacterIndex(pos);
70-
_targetTextBox.ScrollToLine(_targetTextBox.GetLineIndexFromCharacterIndex(pos));
71-
MatchInfo.Text = $"{_currentMatchIndex + 1} of {_matchPositions.Count}";
72-
// Return focus to search box so user can keep typing
79+
_targetTextBox.Select(pos, len);
80+
var lineIndex = _targetTextBox.GetLineIndexFromCharacterIndex(pos);
81+
_targetTextBox.ScrollToLine(lineIndex);
7382
SearchBox.Focus();
83+
MatchInfo.Text = $"{_currentMatchIndex + 1} of {_matchPositions.Count}";
7484
}
7585

7686
private void Next_Click(object sender, RoutedEventArgs e) => FindNext();
7787
private void Prev_Click(object sender, RoutedEventArgs e) => FindPrevious();
7888

7989
public void FindNext() {
90+
if (_matchPositions.Count == 0) FindMatches();
8091
if (_matchPositions.Count == 0) return;
8192
_currentMatchIndex = (_currentMatchIndex + 1) % _matchPositions.Count;
8293
HighlightCurrent();
8394
}
8495

8596
public void FindPrevious() {
97+
if (_matchPositions.Count == 0) FindMatches();
8698
if (_matchPositions.Count == 0) return;
8799
_currentMatchIndex = (_currentMatchIndex - 1 + _matchPositions.Count) % _matchPositions.Count;
88100
HighlightCurrent();
89101
}
90102

91-
private void Close_Click(object sender, RoutedEventArgs e) => Close();
92-
93103
private void SearchBox_TextChanged(object sender, TextChangedEventArgs e) {
94-
FindMatches();
104+
// Clear stale matches when search text changes; new matches built on Enter/nav
105+
_matchPositions.Clear();
106+
_currentMatchIndex = -1;
107+
MatchInfo.Text = "";
95108
}
96109

97110
private void SearchBox_KeyDown(object sender, KeyEventArgs e) {
98111
if (e.Key == Key.Enter || e.Key == Key.F3) {
112+
if (_matchPositions.Count == 0) FindMatches();
99113
if (Keyboard.Modifiers == ModifierKeys.Shift)
100114
FindPrevious();
101115
else
102116
FindNext();
103117
e.Handled = true;
104118
} else if (e.Key == Key.Escape) {
105119
Close();
120+
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Input, new Action(() => {
121+
if (_targetTextBox != null) {
122+
_targetTextBox.Focus();
123+
Keyboard.Focus(_targetTextBox);
124+
}
125+
}));
106126
e.Handled = true;
107127
}
108128
}

Modern/Pages/BaseAddressPage.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<RowDefinition Height="Auto"/>
1010
</Grid.RowDefinitions>
1111

12-
<TextBlock Grid.Row="0" FontSize="16" FontWeight="SemiBold" Margin="0,0,0,4"
12+
<TextBlock Grid.Row="0" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,4"
1313
Text="Provide Module Base Addresses"/>
1414

1515
<Border Grid.Row="1" Background="{DynamicResource WarningBackgroundBrush}" BorderBrush="{DynamicResource WarningBorderBrush}" BorderThickness="1" CornerRadius="4" Padding="10" Margin="0,0,0,8">

Modern/Pages/FieldSelectionPage.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
</Grid.RowDefinitions>
1313

1414
<StackPanel Grid.Row="0" Margin="0,0,0,8">
15-
<TextBlock FontSize="16" FontWeight="SemiBold" Margin="0,0,0,4"
15+
<TextBlock FontSize="15" FontWeight="SemiBold" Margin="0,0,0,4"
1616
Text="Import from XEL Files"/>
1717
<TextBlock FontSize="12" Foreground="Gray"
1818
Text="Select XEL file(s), choose the fields to extract, then click Next to import callstacks."/>

Modern/Pages/InputPage.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</Grid.RowDefinitions>
1111

1212
<StackPanel Grid.Row="0" Margin="0,0,0,8">
13-
<TextBlock FontSize="16" FontWeight="SemiBold" Margin="0,0,0,4"
13+
<TextBlock FontSize="15" FontWeight="SemiBold" Margin="0,0,0,4"
1414
Text="Provide Callstack Input"/>
1515
<TextBlock FontSize="12" Foreground="Gray"
1616
Text="Paste or type raw callstack text below, or drag and drop text files."/>

Modern/Pages/InputSourcePage.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</Grid.RowDefinitions>
1111

1212
<StackPanel Grid.Row="0" Margin="0,0,0,8">
13-
<TextBlock FontSize="16" FontWeight="SemiBold" Margin="0,0,0,4"
13+
<TextBlock FontSize="15" FontWeight="SemiBold" Margin="0,0,0,4"
1414
Text="How would you like to provide input?"/>
1515
<TextBlock FontSize="12" Foreground="Gray"
1616
Text="Choose an input method to get started."/>

Modern/Pages/OptionsPage.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</Grid.RowDefinitions>
1111

1212
<StackPanel Grid.Row="0" Margin="0,0,0,8">
13-
<TextBlock FontSize="16" FontWeight="SemiBold" Margin="0,0,0,4"
13+
<TextBlock FontSize="15" FontWeight="SemiBold" Margin="0,0,0,4"
1414
Text="Output Options"/>
1515
<TextBlock FontSize="12" Foreground="Gray"
1616
Text="Configure how the resolved callstacks should be formatted."/>

Modern/Pages/ResolvePage.xaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
</Grid.RowDefinitions>
2323

2424
<StackPanel Grid.Row="0" Margin="0,0,0,8">
25-
<TextBlock FontSize="16" FontWeight="SemiBold" Margin="0,0,0,4"
25+
<TextBlock FontSize="15" FontWeight="SemiBold" Margin="0,0,0,4"
2626
Text="Resolved Output"/>
2727
<TextBlock FontSize="12" Foreground="Gray"
2828
Text="Symbolized callstack output is shown below."/>
@@ -37,7 +37,8 @@
3737
</StackPanel>
3838
</Button>
3939
<Button Padding="10,6" Margin="8,0,0,0" Click="Find_Click"
40-
Visibility="{Binding HasOutput, Converter={StaticResource BoolToVis}}">
40+
Visibility="{Binding HasOutput, Converter={StaticResource BoolToVis}}"
41+
ToolTip="Find text in output (Ctrl+F)">
4142
<StackPanel Orientation="Horizontal">
4243
<TextBlock Text="&#xE721;" FontFamily="Segoe MDL2 Assets" FontSize="13" VerticalAlignment="Center" Margin="0,0,6,0"/>
4344
<TextBlock Text="Find"/>
@@ -47,7 +48,8 @@
4748

4849
<local:FindBar x:Name="findBar" Grid.Row="2"/>
4950

50-
<TextBox x:Name="outputTextBox" Grid.Row="4" IsReadOnly="True" AcceptsReturn="True"
51+
<TextBox x:Name="outputTextBox" Grid.Row="4" IsReadOnly="True" IsReadOnlyCaretVisible="True"
52+
AcceptsReturn="True"
5153
IsInactiveSelectionHighlightEnabled="True"
5254
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
5355
FontFamily="Consolas" FontSize="13" TextWrapping="NoWrap"

Modern/Pages/ResolvePage.xaml.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,18 @@ public partial class ResolvePage : UserControl {
55
public ResolvePage() {
66
InitializeComponent();
77
findBar.Attach(outputTextBox);
8+
// On mouse wheel, focus the output TextBox so the highlight stays with the text
9+
outputTextBox.PreviewMouseWheel += (s, e) => {
10+
if (findBar.IsOpen) {
11+
outputTextBox.Focus();
12+
Keyboard.Focus(outputTextBox);
13+
}
14+
};
15+
// On keyboard scroll keys or Escape, close find bar
16+
outputTextBox.PreviewKeyDown += (s, e) => {
17+
if (findBar.IsOpen && (e.Key == Key.Escape || e.Key == Key.Up || e.Key == Key.Down || e.Key == Key.PageUp || e.Key == Key.PageDown || e.Key == Key.Home || e.Key == Key.End))
18+
findBar.Close();
19+
};
820
}
921

1022
private void CopyAll_Click(object sender, RoutedEventArgs e) {

Modern/Pages/SymbolConfigPage.xaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
</Grid.RowDefinitions>
1818

1919
<StackPanel Grid.Row="0" Margin="0,0,0,8">
20-
<TextBlock FontSize="16" FontWeight="SemiBold" Margin="0,0,0,4"
20+
<TextBlock FontSize="15" FontWeight="SemiBold" Margin="0,0,0,4"
2121
Text="Configure Symbol Paths"/>
2222
<TextBlock FontSize="12" Foreground="Gray"
2323
Text="Use preset symbol downloads for a known SQL Server build, or set custom PDB search paths."/>
@@ -43,7 +43,7 @@
4343
<TextBlock Text="Detected SQL Server " FontWeight="SemiBold" FontSize="13"/>
4444
<TextBlock Text="{Binding DetectedBuildVersion}" FontWeight="SemiBold" FontSize="13"/>
4545
</StackPanel>
46-
<TextBlock Text="{Binding DetectedBuildDetails}" FontSize="11.5" Foreground="Gray" TextTrimming="CharacterEllipsis"/>
46+
<TextBlock Text="{Binding DetectedBuildDetails}" FontSize="12" Foreground="Gray" TextTrimming="CharacterEllipsis"/>
4747
</StackPanel>
4848
<Button Grid.Column="2" Padding="12,6" Click="DownloadDetectedBuild_Click"
4949
Style="{DynamicResource AccentButtonStyle}">
@@ -72,7 +72,7 @@
7272
Foreground="{DynamicResource SystemControlForegroundAccentBrush}"/>
7373
<StackPanel Grid.Column="1" VerticalAlignment="Center">
7474
<TextBlock Text="XML frames with PDB info detected" FontWeight="SemiBold" FontSize="13"/>
75-
<TextBlock FontSize="11.5" Foreground="Gray" TextTrimming="CharacterEllipsis">
75+
<TextBlock FontSize="12" Foreground="Gray" TextTrimming="CharacterEllipsis">
7676
<Run Text="Modules:"/>
7777
<Run Text="{Binding DetectedPdbModules, Mode=OneWay}"/>
7878
</TextBlock>
@@ -107,7 +107,7 @@
107107
<!-- PDB Paths (manual) -->
108108
<GroupBox Grid.Row="3" Header="PDB Symbol Paths" Padding="6" Margin="0,0,0,8">
109109
<StackPanel>
110-
<TextBlock FontSize="11" Foreground="Gray" Margin="0,0,0,4"
110+
<TextBlock FontSize="11.5" Foreground="Gray" Margin="0,0,0,4"
111111
Text="Local folder(s), UNC path(s), or WinDbg-style symbol server(s). If using multiple paths; separate using semicolons."/>
112112
<DockPanel>
113113
<ToggleButton DockPanel.Dock="Right" IsChecked="{Binding PinPdbPaths}"

Modern/Pages/SymbolConfigPage.xaml.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ public SymbolConfigPage() {
99
}
1010

1111
private void UseSymbolServer_Click(object sender, RoutedEventArgs e) {
12+
ViewModel.HasXmlFrameInput = false;
1213
ViewModel.UpdatePdbPath(@"SRV*c:\temp\symcache*https://msdl.microsoft.com/download/symbols");
1314
ViewModel.StatusMessage = "Symbol server path added. Ready to resolve!";
1415
ViewModel.HighlightResolve = true;
1516
}
1617

1718
private async void DownloadDetectedBuild_Click(object sender, RoutedEventArgs e) {
1819
await ViewModel.DownloadSymbolsForDetectedBuildAsync();
20+
ViewModel.DetectedBuildInfo = null;
1921
}
2022

2123
private void BrowsePdbPath_Click(object sender, RoutedEventArgs e) {

0 commit comments

Comments
 (0)