Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Dashboard/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ protected override void OnStartup(StartupEventArgs e)

base.OnStartup(e);

// Apply saved color theme before the main window is shown
var prefs = new Services.UserPreferencesService().GetPreferences();
ThemeManager.Apply(prefs.ColorTheme ?? "Dark");

// Register global exception handlers
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
DispatcherUnhandledException += OnDispatcherUnhandledException;
Expand Down
6 changes: 1 addition & 5 deletions Dashboard/Controls/AlertsHistoryContent.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/DarkTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>

<!-- Context Menu for DataGrid Copy/Export -->
<ContextMenu x:Key="DataGridContextMenu">
<MenuItem Header="Copy Cell" Click="CopyCell_Click">
Expand Down Expand Up @@ -74,7 +70,7 @@
<ComboBoxItem Content="All Servers" IsSelected="True"/>
</ComboBox>
<Button Content="Refresh" Click="RefreshButton_Click" Margin="12,0,0,0" Padding="10,4" MinWidth="70"
Style="{StaticResource SuccessButton}"/>
Style="{DynamicResource SuccessButton}"/>
<Button x:Name="DismissSelectedButton" Content="Dismiss Selected" Click="DismissSelected_Click"
Margin="8,0,0,0" Padding="10,4" MinWidth="90" IsEnabled="False"/>
<Button Content="Dismiss All" Click="DismissAll_Click"
Expand Down
4 changes: 0 additions & 4 deletions Dashboard/Controls/CriticalIssuesContent.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/DarkTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>

<!-- Context Menu for DataGrid Copy/Export -->
<ContextMenu x:Key="DataGridContextMenu">
<MenuItem Header="Copy Cell" Click="CopyCell_Click">
Expand Down
8 changes: 2 additions & 6 deletions Dashboard/Controls/DailySummaryContent.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/DarkTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>

<!-- Context Menu for DataGrid Copy/Export -->
<ContextMenu x:Key="DataGridContextMenu">
<MenuItem Header="Copy Cell" Click="CopyCell_Click">
Expand Down Expand Up @@ -43,9 +39,9 @@
<!-- Date Selection Controls -->
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="10,5" Background="{DynamicResource BackgroundLightBrush}" Height="40">
<TextBlock Text="Summary Date:" VerticalAlignment="Center" Margin="5,0" FontWeight="Bold"/>
<Button x:Name="DailySummaryTodayButton" Content="Today" Click="DailySummaryToday_Click" Margin="5,0" Padding="8,4" MinWidth="60" Style="{StaticResource AccentButton}"/>
<Button x:Name="DailySummaryTodayButton" Content="Today" Click="DailySummaryToday_Click" Margin="5,0" Padding="8,4" MinWidth="60" Style="{DynamicResource AccentButton}"/>
<DatePicker x:Name="DailySummaryDatePicker" Width="120" Margin="5,0" SelectedDateChanged="DailySummaryDate_Changed" CalendarOpened="DatePicker_CalendarOpened"/>
<Button Content="Refresh" Click="DailySummary_Refresh_Click" Margin="10,0,2,0" Padding="10,4" MinWidth="70" Style="{StaticResource SuccessButton}"/>
<Button Content="Refresh" Click="DailySummary_Refresh_Click" Margin="10,0,2,0" Padding="10,4" MinWidth="70" Style="{DynamicResource SuccessButton}"/>
<TextBlock x:Name="DailySummaryIndicator"
Text="Showing: Today"
Margin="10,0"
Expand Down
4 changes: 2 additions & 2 deletions Dashboard/Controls/DailySummaryContent.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,15 @@ private void DatePicker_CalendarOpened(object sender, RoutedEventArgs e)
var popup = datePicker.Template.FindName("PART_Popup", datePicker) as System.Windows.Controls.Primitives.Popup;
if (popup?.Child is System.Windows.Controls.Calendar calendar)
{
TabHelpers.ApplyDarkThemeToCalendar(calendar);
TabHelpers.ApplyThemeToCalendar(calendar);
}
else
{
// Fallback: search visual tree
var calendar2 = FindVisualChild<System.Windows.Controls.Calendar>(datePicker);
if (calendar2 != null)
{
TabHelpers.ApplyDarkThemeToCalendar(calendar2);
TabHelpers.ApplyThemeToCalendar(calendar2);
}
}
}), System.Windows.Threading.DispatcherPriority.Loaded);
Expand Down
8 changes: 0 additions & 8 deletions Dashboard/Controls/LandingPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@
xmlns:local="clr-namespace:PerformanceMonitorDashboard.Controls"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="1000">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/DarkTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>

<Grid Background="{DynamicResource BackgroundBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
Expand Down
4 changes: 0 additions & 4 deletions Dashboard/Controls/MemoryContent.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@
d:DesignHeight="600" d:DesignWidth="1200">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/DarkTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>

<!-- Context Menu for DataGrid Copy/Export -->
<ContextMenu x:Key="DataGridContextMenu">
<MenuItem Header="Copy Cell" Click="CopyCell_Click">
Expand Down
41 changes: 28 additions & 13 deletions Dashboard/Controls/MemoryContent.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2026 Erik Darling, Darling Data LLC
*
* This file is part of the SQL Server Performance Monitor.
Expand Down Expand Up @@ -81,14 +81,16 @@ public MemoryContent()
InitializeComponent();
SetupChartContextMenus();
Loaded += OnLoaded;
Helpers.ThemeManager.ThemeChanged += OnThemeChanged;
Unloaded += (_, _) => Helpers.ThemeManager.ThemeChanged -= OnThemeChanged;

// Apply dark theme immediately so charts don't flash white before data loads
TabHelpers.ApplyDarkModeToChart(MemoryStatsOverviewChart);
TabHelpers.ApplyDarkModeToChart(MemoryGrantSizingChart);
TabHelpers.ApplyDarkModeToChart(MemoryGrantActivityChart);
TabHelpers.ApplyDarkModeToChart(MemoryClerksChart);
TabHelpers.ApplyDarkModeToChart(PlanCacheChart);
TabHelpers.ApplyDarkModeToChart(MemoryPressureEventsChart);
TabHelpers.ApplyThemeToChart(MemoryStatsOverviewChart);
TabHelpers.ApplyThemeToChart(MemoryGrantSizingChart);
TabHelpers.ApplyThemeToChart(MemoryGrantActivityChart);
TabHelpers.ApplyThemeToChart(MemoryClerksChart);
TabHelpers.ApplyThemeToChart(PlanCacheChart);
TabHelpers.ApplyThemeToChart(MemoryPressureEventsChart);

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

private void OnThemeChanged(string _)
{
foreach (var field in GetType().GetFields(
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance))
{
if (field.GetValue(this) is ScottPlot.WPF.WpfPlot chart)
{
Helpers.TabHelpers.ApplyThemeToChart(chart);
chart.Refresh();
}
}
}

private void SetupChartContextMenus()
{
// Memory Stats Overview chart
Expand Down Expand Up @@ -212,7 +227,7 @@ private void LoadMemoryStatsOverviewChart(List<MemoryStatsItem> memoryData, int
}
MemoryStatsOverviewChart.Plot.Clear();
_memoryStatsOverviewHover?.Clear();
TabHelpers.ApplyDarkModeToChart(MemoryStatsOverviewChart);
TabHelpers.ApplyThemeToChart(MemoryStatsOverviewChart);

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

var poolIds = aggregated.Select(d => d.PoolId).Distinct().OrderBy(id => id).ToList();
int colorIndex = 0;
Expand Down Expand Up @@ -556,7 +571,7 @@ private void LoadMemoryGrantActivityChart(List<PoolGrantPoint> aggregated, int h
}
MemoryGrantActivityChart.Plot.Clear();
_memoryGrantActivityHover?.Clear();
TabHelpers.ApplyDarkModeToChart(MemoryGrantActivityChart);
TabHelpers.ApplyThemeToChart(MemoryGrantActivityChart);

var poolIds = aggregated.Select(d => d.PoolId).Distinct().OrderBy(id => id).ToList();
int colorIndex = 0;
Expand Down Expand Up @@ -727,7 +742,7 @@ private async System.Threading.Tasks.Task UpdateMemoryClerksChartFromPickerAsync
}
MemoryClerksChart.Plot.Clear();
_memoryClerksHover?.Clear();
TabHelpers.ApplyDarkModeToChart(MemoryClerksChart);
TabHelpers.ApplyThemeToChart(MemoryClerksChart);

DateTime rangeEnd = _memoryClerksToDate ?? Helpers.ServerTimeHelper.ServerNow;
DateTime rangeStart = _memoryClerksFromDate ?? rangeEnd.AddHours(-_memoryClerksHoursBack);
Expand Down Expand Up @@ -864,7 +879,7 @@ private void LoadPlanCacheChart(IEnumerable<PlanCacheStatsItem> data, int hoursB
}
PlanCacheChart.Plot.Clear();
_planCacheHover?.Clear();
TabHelpers.ApplyDarkModeToChart(PlanCacheChart);
TabHelpers.ApplyThemeToChart(PlanCacheChart);

var dataList = data?.ToList() ?? new List<PlanCacheStatsItem>();
if (dataList.Count > 0)
Expand Down Expand Up @@ -1005,7 +1020,7 @@ private void LoadMemoryPressureEventsChart(IEnumerable<MemoryPressureEventItem>
}
MemoryPressureEventsChart.Plot.Clear();
_memoryPressureEventsHover?.Clear();
TabHelpers.ApplyDarkModeToChart(MemoryPressureEventsChart);
TabHelpers.ApplyThemeToChart(MemoryPressureEventsChart);

// Only chart HIGH severity events
var dataList = data?.Where(d => d.Severity.Equals("HIGH", StringComparison.OrdinalIgnoreCase))
Expand Down
30 changes: 23 additions & 7 deletions Dashboard/Controls/QueryPerformanceContent.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2026 Erik Darling, Darling Data LLC
*
* This file is part of the SQL Server Performance Monitor.
Expand Down Expand Up @@ -133,6 +133,7 @@ public QueryPerformanceContent()
SetupChartSaveMenus();
Loaded += OnLoaded;
Unloaded += OnUnloaded;
Helpers.ThemeManager.ThemeChanged += OnThemeChanged;

_queryDurationHover = new Helpers.ChartHoverHelper(QueryPerfTrendsQueryChart, "ms/sec");
_procDurationHover = new Helpers.ChartHoverHelper(QueryPerfTrendsProcChart, "ms/sec");
Expand Down Expand Up @@ -169,15 +170,30 @@ private void OnUnloaded(object sender, RoutedEventArgs e)
_queryStoreUnfilteredData = null;
_qsRegressionsUnfilteredData = null;
_lrqPatternsUnfilteredData = null;

Helpers.ThemeManager.ThemeChanged -= OnThemeChanged;
}

private void OnThemeChanged(string _)
{
foreach (var field in GetType().GetFields(
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance))
{
if (field.GetValue(this) is ScottPlot.WPF.WpfPlot chart)
{
Helpers.TabHelpers.ApplyThemeToChart(chart);
chart.Refresh();
}
}
}

private void OnLoaded(object sender, RoutedEventArgs e)
{
// Initialize charts with dark mode immediately (before data is loaded)
TabHelpers.ApplyDarkModeToChart(QueryPerfTrendsQueryChart);
TabHelpers.ApplyDarkModeToChart(QueryPerfTrendsProcChart);
TabHelpers.ApplyDarkModeToChart(QueryPerfTrendsQsChart);
TabHelpers.ApplyDarkModeToChart(QueryPerfTrendsExecChart);
TabHelpers.ApplyThemeToChart(QueryPerfTrendsQueryChart);
TabHelpers.ApplyThemeToChart(QueryPerfTrendsProcChart);
TabHelpers.ApplyThemeToChart(QueryPerfTrendsQsChart);
TabHelpers.ApplyThemeToChart(QueryPerfTrendsExecChart);
QueryPerfTrendsQueryChart.Refresh();
QueryPerfTrendsProcChart.Refresh();
QueryPerfTrendsQsChart.Refresh();
Expand Down Expand Up @@ -1594,7 +1610,7 @@ private void LoadDurationChart(WpfPlot chart, IEnumerable<DurationTrendItem> tre
}
chart.Plot.Clear();
hover?.Clear();
TabHelpers.ApplyDarkModeToChart(chart);
TabHelpers.ApplyThemeToChart(chart);

var dataList = (trendData ?? Enumerable.Empty<DurationTrendItem>())
.OrderBy(d => d.CollectionTime)
Expand Down Expand Up @@ -1649,7 +1665,7 @@ private void LoadExecChart(IEnumerable<ExecutionTrendItem> execTrends, int hours
}
QueryPerfTrendsExecChart.Plot.Clear();
_execTrendsHover?.Clear();
TabHelpers.ApplyDarkModeToChart(QueryPerfTrendsExecChart);
TabHelpers.ApplyThemeToChart(QueryPerfTrendsExecChart);

var dataList = (execTrends ?? Enumerable.Empty<ExecutionTrendItem>())
.OrderBy(d => d.CollectionTime)
Expand Down
4 changes: 2 additions & 2 deletions Dashboard/Controls/ResourceMetricsContent.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="5,5,5,2">
<TextBlock Text="Select Wait Types" FontWeight="Bold" VerticalAlignment="Center" Foreground="{DynamicResource ForegroundBrush}"/>
<Button Content="Refresh" Click="WaitStatsDetail_Refresh_Click" Margin="10,0,0,0" Padding="8,2" Style="{StaticResource SuccessButton}" FontSize="11"/>
<Button Content="Refresh" Click="WaitStatsDetail_Refresh_Click" Margin="10,0,0,0" Padding="8,2" Style="{DynamicResource SuccessButton}" FontSize="11"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="5,2">
<Button Content="Top Waits" Click="WaitTypes_SelectAll_Click" Padding="6,2" FontSize="10" Margin="0,0,5,0"/>
Expand Down Expand Up @@ -299,7 +299,7 @@
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="5,5,5,2">
<TextBlock Text="Select Counters" FontWeight="Bold" VerticalAlignment="Center" Foreground="{DynamicResource ForegroundBrush}"/>
<Button Content="Refresh" Click="PerfmonCounters_Refresh_Click" Margin="10,0,0,0" Padding="8,2" Style="{StaticResource SuccessButton}" FontSize="11"/>
<Button Content="Refresh" Click="PerfmonCounters_Refresh_Click" Margin="10,0,0,0" Padding="8,2" Style="{DynamicResource SuccessButton}" FontSize="11"/>
</StackPanel>
<ComboBox Grid.Row="1" x:Name="PerfmonPackCombo"
SelectionChanged="PerfmonPack_SelectionChanged"
Expand Down
Loading
Loading