Skip to content

Commit 213c529

Browse files
Merge pull request #347 from ClaudioESSilva/feature/AddLightTheme
[FEATURE] Add light theme
2 parents 13d61c1 + bf15fce commit 213c529

51 files changed

Lines changed: 5850 additions & 488 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Dashboard/App.xaml.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ protected override void OnStartup(StartupEventArgs e)
3737

3838
base.OnStartup(e);
3939

40+
// Apply saved color theme before the main window is shown
41+
var prefs = new Services.UserPreferencesService().GetPreferences();
42+
ThemeManager.Apply(prefs.ColorTheme ?? "Dark");
43+
4044
// Register global exception handlers
4145
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
4246
DispatcherUnhandledException += OnDispatcherUnhandledException;

Dashboard/Controls/AlertsHistoryContent.xaml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@
77
d:DesignHeight="450" d:DesignWidth="800">
88
<UserControl.Resources>
99
<ResourceDictionary>
10-
<ResourceDictionary.MergedDictionaries>
11-
<ResourceDictionary Source="pack://application:,,,/Themes/DarkTheme.xaml"/>
12-
</ResourceDictionary.MergedDictionaries>
13-
1410
<!-- Context Menu for DataGrid Copy/Export -->
1511
<ContextMenu x:Key="DataGridContextMenu">
1612
<MenuItem Header="Copy Cell" Click="CopyCell_Click">
@@ -74,7 +70,7 @@
7470
<ComboBoxItem Content="All Servers" IsSelected="True"/>
7571
</ComboBox>
7672
<Button Content="Refresh" Click="RefreshButton_Click" Margin="12,0,0,0" Padding="10,4" MinWidth="70"
77-
Style="{StaticResource SuccessButton}"/>
73+
Style="{DynamicResource SuccessButton}"/>
7874
<Button x:Name="DismissSelectedButton" Content="Dismiss Selected" Click="DismissSelected_Click"
7975
Margin="8,0,0,0" Padding="10,4" MinWidth="90" IsEnabled="False"/>
8076
<Button Content="Dismiss All" Click="DismissAll_Click"

Dashboard/Controls/CriticalIssuesContent.xaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@
88
d:DesignHeight="450" d:DesignWidth="800">
99
<UserControl.Resources>
1010
<ResourceDictionary>
11-
<ResourceDictionary.MergedDictionaries>
12-
<ResourceDictionary Source="pack://application:,,,/Themes/DarkTheme.xaml"/>
13-
</ResourceDictionary.MergedDictionaries>
14-
1511
<!-- Context Menu for DataGrid Copy/Export -->
1612
<ContextMenu x:Key="DataGridContextMenu">
1713
<MenuItem Header="Copy Cell" Click="CopyCell_Click">

Dashboard/Controls/DailySummaryContent.xaml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@
88
d:DesignHeight="450" d:DesignWidth="800">
99
<UserControl.Resources>
1010
<ResourceDictionary>
11-
<ResourceDictionary.MergedDictionaries>
12-
<ResourceDictionary Source="pack://application:,,,/Themes/DarkTheme.xaml"/>
13-
</ResourceDictionary.MergedDictionaries>
14-
1511
<!-- Context Menu for DataGrid Copy/Export -->
1612
<ContextMenu x:Key="DataGridContextMenu">
1713
<MenuItem Header="Copy Cell" Click="CopyCell_Click">
@@ -43,9 +39,9 @@
4339
<!-- Date Selection Controls -->
4440
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="10,5" Background="{DynamicResource BackgroundLightBrush}" Height="40">
4541
<TextBlock Text="Summary Date:" VerticalAlignment="Center" Margin="5,0" FontWeight="Bold"/>
46-
<Button x:Name="DailySummaryTodayButton" Content="Today" Click="DailySummaryToday_Click" Margin="5,0" Padding="8,4" MinWidth="60" Style="{StaticResource AccentButton}"/>
42+
<Button x:Name="DailySummaryTodayButton" Content="Today" Click="DailySummaryToday_Click" Margin="5,0" Padding="8,4" MinWidth="60" Style="{DynamicResource AccentButton}"/>
4743
<DatePicker x:Name="DailySummaryDatePicker" Width="120" Margin="5,0" SelectedDateChanged="DailySummaryDate_Changed" CalendarOpened="DatePicker_CalendarOpened"/>
48-
<Button Content="Refresh" Click="DailySummary_Refresh_Click" Margin="10,0,2,0" Padding="10,4" MinWidth="70" Style="{StaticResource SuccessButton}"/>
44+
<Button Content="Refresh" Click="DailySummary_Refresh_Click" Margin="10,0,2,0" Padding="10,4" MinWidth="70" Style="{DynamicResource SuccessButton}"/>
4945
<TextBlock x:Name="DailySummaryIndicator"
5046
Text="Showing: Today"
5147
Margin="10,0"

Dashboard/Controls/DailySummaryContent.xaml.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,15 +145,15 @@ private void DatePicker_CalendarOpened(object sender, RoutedEventArgs e)
145145
var popup = datePicker.Template.FindName("PART_Popup", datePicker) as System.Windows.Controls.Primitives.Popup;
146146
if (popup?.Child is System.Windows.Controls.Calendar calendar)
147147
{
148-
TabHelpers.ApplyDarkThemeToCalendar(calendar);
148+
TabHelpers.ApplyThemeToCalendar(calendar);
149149
}
150150
else
151151
{
152152
// Fallback: search visual tree
153153
var calendar2 = FindVisualChild<System.Windows.Controls.Calendar>(datePicker);
154154
if (calendar2 != null)
155155
{
156-
TabHelpers.ApplyDarkThemeToCalendar(calendar2);
156+
TabHelpers.ApplyThemeToCalendar(calendar2);
157157
}
158158
}
159159
}), System.Windows.Threading.DispatcherPriority.Loaded);

Dashboard/Controls/LandingPage.xaml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,6 @@
66
xmlns:local="clr-namespace:PerformanceMonitorDashboard.Controls"
77
mc:Ignorable="d"
88
d:DesignHeight="600" d:DesignWidth="1000">
9-
<UserControl.Resources>
10-
<ResourceDictionary>
11-
<ResourceDictionary.MergedDictionaries>
12-
<ResourceDictionary Source="pack://application:,,,/Themes/DarkTheme.xaml"/>
13-
</ResourceDictionary.MergedDictionaries>
14-
</ResourceDictionary>
15-
</UserControl.Resources>
16-
179
<Grid Background="{DynamicResource BackgroundBrush}">
1810
<Grid.RowDefinitions>
1911
<RowDefinition Height="Auto"/>

Dashboard/Controls/MemoryContent.xaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@
99
d:DesignHeight="600" d:DesignWidth="1200">
1010
<UserControl.Resources>
1111
<ResourceDictionary>
12-
<ResourceDictionary.MergedDictionaries>
13-
<ResourceDictionary Source="pack://application:,,,/Themes/DarkTheme.xaml"/>
14-
</ResourceDictionary.MergedDictionaries>
15-
1612
<!-- Context Menu for DataGrid Copy/Export -->
1713
<ContextMenu x:Key="DataGridContextMenu">
1814
<MenuItem Header="Copy Cell" Click="CopyCell_Click">

Dashboard/Controls/MemoryContent.xaml.cs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright (c) 2026 Erik Darling, Darling Data LLC
33
*
44
* This file is part of the SQL Server Performance Monitor.
@@ -81,14 +81,16 @@ public MemoryContent()
8181
InitializeComponent();
8282
SetupChartContextMenus();
8383
Loaded += OnLoaded;
84+
Helpers.ThemeManager.ThemeChanged += OnThemeChanged;
85+
Unloaded += (_, _) => Helpers.ThemeManager.ThemeChanged -= OnThemeChanged;
8486

8587
// Apply dark theme immediately so charts don't flash white before data loads
86-
TabHelpers.ApplyDarkModeToChart(MemoryStatsOverviewChart);
87-
TabHelpers.ApplyDarkModeToChart(MemoryGrantSizingChart);
88-
TabHelpers.ApplyDarkModeToChart(MemoryGrantActivityChart);
89-
TabHelpers.ApplyDarkModeToChart(MemoryClerksChart);
90-
TabHelpers.ApplyDarkModeToChart(PlanCacheChart);
91-
TabHelpers.ApplyDarkModeToChart(MemoryPressureEventsChart);
88+
TabHelpers.ApplyThemeToChart(MemoryStatsOverviewChart);
89+
TabHelpers.ApplyThemeToChart(MemoryGrantSizingChart);
90+
TabHelpers.ApplyThemeToChart(MemoryGrantActivityChart);
91+
TabHelpers.ApplyThemeToChart(MemoryClerksChart);
92+
TabHelpers.ApplyThemeToChart(PlanCacheChart);
93+
TabHelpers.ApplyThemeToChart(MemoryPressureEventsChart);
9294

9395
_memoryStatsOverviewHover = new Helpers.ChartHoverHelper(MemoryStatsOverviewChart, "MB");
9496
_memoryGrantSizingHover = new Helpers.ChartHoverHelper(MemoryGrantSizingChart, "MB");
@@ -103,6 +105,19 @@ private void OnLoaded(object sender, RoutedEventArgs e)
103105
// No grids to configure - all tabs are chart-only now
104106
}
105107

108+
private void OnThemeChanged(string _)
109+
{
110+
foreach (var field in GetType().GetFields(
111+
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance))
112+
{
113+
if (field.GetValue(this) is ScottPlot.WPF.WpfPlot chart)
114+
{
115+
Helpers.TabHelpers.ApplyThemeToChart(chart);
116+
chart.Refresh();
117+
}
118+
}
119+
}
120+
106121
private void SetupChartContextMenus()
107122
{
108123
// Memory Stats Overview chart
@@ -212,7 +227,7 @@ private void LoadMemoryStatsOverviewChart(List<MemoryStatsItem> memoryData, int
212227
}
213228
MemoryStatsOverviewChart.Plot.Clear();
214229
_memoryStatsOverviewHover?.Clear();
215-
TabHelpers.ApplyDarkModeToChart(MemoryStatsOverviewChart);
230+
TabHelpers.ApplyThemeToChart(MemoryStatsOverviewChart);
216231

217232
var dataList = memoryData?.OrderBy(d => d.CollectionTime).ToList() ?? new List<MemoryStatsItem>();
218233
// Total Memory series with gap filling
@@ -487,7 +502,7 @@ private void LoadMemoryGrantSizingChart(List<PoolGrantPoint> aggregated, int hou
487502
}
488503
MemoryGrantSizingChart.Plot.Clear();
489504
_memoryGrantSizingHover?.Clear();
490-
TabHelpers.ApplyDarkModeToChart(MemoryGrantSizingChart);
505+
TabHelpers.ApplyThemeToChart(MemoryGrantSizingChart);
491506

492507
var poolIds = aggregated.Select(d => d.PoolId).Distinct().OrderBy(id => id).ToList();
493508
int colorIndex = 0;
@@ -556,7 +571,7 @@ private void LoadMemoryGrantActivityChart(List<PoolGrantPoint> aggregated, int h
556571
}
557572
MemoryGrantActivityChart.Plot.Clear();
558573
_memoryGrantActivityHover?.Clear();
559-
TabHelpers.ApplyDarkModeToChart(MemoryGrantActivityChart);
574+
TabHelpers.ApplyThemeToChart(MemoryGrantActivityChart);
560575

561576
var poolIds = aggregated.Select(d => d.PoolId).Distinct().OrderBy(id => id).ToList();
562577
int colorIndex = 0;
@@ -727,7 +742,7 @@ private async System.Threading.Tasks.Task UpdateMemoryClerksChartFromPickerAsync
727742
}
728743
MemoryClerksChart.Plot.Clear();
729744
_memoryClerksHover?.Clear();
730-
TabHelpers.ApplyDarkModeToChart(MemoryClerksChart);
745+
TabHelpers.ApplyThemeToChart(MemoryClerksChart);
731746

732747
DateTime rangeEnd = _memoryClerksToDate ?? Helpers.ServerTimeHelper.ServerNow;
733748
DateTime rangeStart = _memoryClerksFromDate ?? rangeEnd.AddHours(-_memoryClerksHoursBack);
@@ -864,7 +879,7 @@ private void LoadPlanCacheChart(IEnumerable<PlanCacheStatsItem> data, int hoursB
864879
}
865880
PlanCacheChart.Plot.Clear();
866881
_planCacheHover?.Clear();
867-
TabHelpers.ApplyDarkModeToChart(PlanCacheChart);
882+
TabHelpers.ApplyThemeToChart(PlanCacheChart);
868883

869884
var dataList = data?.ToList() ?? new List<PlanCacheStatsItem>();
870885
if (dataList.Count > 0)
@@ -1005,7 +1020,7 @@ private void LoadMemoryPressureEventsChart(IEnumerable<MemoryPressureEventItem>
10051020
}
10061021
MemoryPressureEventsChart.Plot.Clear();
10071022
_memoryPressureEventsHover?.Clear();
1008-
TabHelpers.ApplyDarkModeToChart(MemoryPressureEventsChart);
1023+
TabHelpers.ApplyThemeToChart(MemoryPressureEventsChart);
10091024

10101025
// Only chart HIGH severity events
10111026
var dataList = data?.Where(d => d.Severity.Equals("HIGH", StringComparison.OrdinalIgnoreCase))

Dashboard/Controls/QueryPerformanceContent.xaml.cs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright (c) 2026 Erik Darling, Darling Data LLC
33
*
44
* This file is part of the SQL Server Performance Monitor.
@@ -133,6 +133,7 @@ public QueryPerformanceContent()
133133
SetupChartSaveMenus();
134134
Loaded += OnLoaded;
135135
Unloaded += OnUnloaded;
136+
Helpers.ThemeManager.ThemeChanged += OnThemeChanged;
136137

137138
_queryDurationHover = new Helpers.ChartHoverHelper(QueryPerfTrendsQueryChart, "ms/sec");
138139
_procDurationHover = new Helpers.ChartHoverHelper(QueryPerfTrendsProcChart, "ms/sec");
@@ -169,15 +170,30 @@ private void OnUnloaded(object sender, RoutedEventArgs e)
169170
_queryStoreUnfilteredData = null;
170171
_qsRegressionsUnfilteredData = null;
171172
_lrqPatternsUnfilteredData = null;
173+
174+
Helpers.ThemeManager.ThemeChanged -= OnThemeChanged;
175+
}
176+
177+
private void OnThemeChanged(string _)
178+
{
179+
foreach (var field in GetType().GetFields(
180+
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance))
181+
{
182+
if (field.GetValue(this) is ScottPlot.WPF.WpfPlot chart)
183+
{
184+
Helpers.TabHelpers.ApplyThemeToChart(chart);
185+
chart.Refresh();
186+
}
187+
}
172188
}
173189

174190
private void OnLoaded(object sender, RoutedEventArgs e)
175191
{
176192
// Initialize charts with dark mode immediately (before data is loaded)
177-
TabHelpers.ApplyDarkModeToChart(QueryPerfTrendsQueryChart);
178-
TabHelpers.ApplyDarkModeToChart(QueryPerfTrendsProcChart);
179-
TabHelpers.ApplyDarkModeToChart(QueryPerfTrendsQsChart);
180-
TabHelpers.ApplyDarkModeToChart(QueryPerfTrendsExecChart);
193+
TabHelpers.ApplyThemeToChart(QueryPerfTrendsQueryChart);
194+
TabHelpers.ApplyThemeToChart(QueryPerfTrendsProcChart);
195+
TabHelpers.ApplyThemeToChart(QueryPerfTrendsQsChart);
196+
TabHelpers.ApplyThemeToChart(QueryPerfTrendsExecChart);
181197
QueryPerfTrendsQueryChart.Refresh();
182198
QueryPerfTrendsProcChart.Refresh();
183199
QueryPerfTrendsQsChart.Refresh();
@@ -1594,7 +1610,7 @@ private void LoadDurationChart(WpfPlot chart, IEnumerable<DurationTrendItem> tre
15941610
}
15951611
chart.Plot.Clear();
15961612
hover?.Clear();
1597-
TabHelpers.ApplyDarkModeToChart(chart);
1613+
TabHelpers.ApplyThemeToChart(chart);
15981614

15991615
var dataList = (trendData ?? Enumerable.Empty<DurationTrendItem>())
16001616
.OrderBy(d => d.CollectionTime)
@@ -1649,7 +1665,7 @@ private void LoadExecChart(IEnumerable<ExecutionTrendItem> execTrends, int hours
16491665
}
16501666
QueryPerfTrendsExecChart.Plot.Clear();
16511667
_execTrendsHover?.Clear();
1652-
TabHelpers.ApplyDarkModeToChart(QueryPerfTrendsExecChart);
1668+
TabHelpers.ApplyThemeToChart(QueryPerfTrendsExecChart);
16531669

16541670
var dataList = (execTrends ?? Enumerable.Empty<ExecutionTrendItem>())
16551671
.OrderBy(d => d.CollectionTime)

Dashboard/Controls/ResourceMetricsContent.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
</Grid.RowDefinitions>
113113
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="5,5,5,2">
114114
<TextBlock Text="Select Wait Types" FontWeight="Bold" VerticalAlignment="Center" Foreground="{DynamicResource ForegroundBrush}"/>
115-
<Button Content="Refresh" Click="WaitStatsDetail_Refresh_Click" Margin="10,0,0,0" Padding="8,2" Style="{StaticResource SuccessButton}" FontSize="11"/>
115+
<Button Content="Refresh" Click="WaitStatsDetail_Refresh_Click" Margin="10,0,0,0" Padding="8,2" Style="{DynamicResource SuccessButton}" FontSize="11"/>
116116
</StackPanel>
117117
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="5,2">
118118
<Button Content="Top Waits" Click="WaitTypes_SelectAll_Click" Padding="6,2" FontSize="10" Margin="0,0,5,0"/>
@@ -299,7 +299,7 @@
299299
</Grid.RowDefinitions>
300300
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="5,5,5,2">
301301
<TextBlock Text="Select Counters" FontWeight="Bold" VerticalAlignment="Center" Foreground="{DynamicResource ForegroundBrush}"/>
302-
<Button Content="Refresh" Click="PerfmonCounters_Refresh_Click" Margin="10,0,0,0" Padding="8,2" Style="{StaticResource SuccessButton}" FontSize="11"/>
302+
<Button Content="Refresh" Click="PerfmonCounters_Refresh_Click" Margin="10,0,0,0" Padding="8,2" Style="{DynamicResource SuccessButton}" FontSize="11"/>
303303
</StackPanel>
304304
<ComboBox Grid.Row="1" x:Name="PerfmonPackCombo"
305305
SelectionChanged="PerfmonPack_SelectionChanged"

0 commit comments

Comments
 (0)