diff --git a/DbFirst.BlazorWebApp/Components/App.razor b/DbFirst.BlazorWebApp/Components/App.razor
index f6e8697..3a4ea34 100644
--- a/DbFirst.BlazorWebApp/Components/App.razor
+++ b/DbFirst.BlazorWebApp/Components/App.razor
@@ -24,6 +24,14 @@
+
diff --git a/DbFirst.BlazorWebApp/Components/Layout/MainLayout.razor b/DbFirst.BlazorWebApp/Components/Layout/MainLayout.razor
index 2f4e964..77cd534 100644
--- a/DbFirst.BlazorWebApp/Components/Layout/MainLayout.razor
+++ b/DbFirst.BlazorWebApp/Components/Layout/MainLayout.razor
@@ -1,8 +1,9 @@
@inherits LayoutComponentBase
@implements IDisposable
@inject ThemeState ThemeState
+@inject IJSRuntime JS
-
+
@@ -33,9 +34,43 @@
@code {
+ private bool _isInteractive;
+
protected override void OnInitialized()
{
- ThemeState.OnChange += StateHasChanged;
+ ThemeState.OnChange += OnThemeChanged;
+ }
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (firstRender)
+ {
+ _isInteractive = true;
+ }
+ await ApplyDxDarkOverrideAsync();
+ }
+
+ private async void OnThemeChanged()
+ {
+ StateHasChanged();
+ if (_isInteractive)
+ {
+ await ApplyDxDarkOverrideAsync();
+ }
+ }
+
+ private async Task ApplyDxDarkOverrideAsync()
+ {
+ if (!_isInteractive) return;
+ try
+ {
+ bool needsOverride = ThemeState.IsDarkMode && !ThemeState.IsNativeDarkTheme;
+ await JS.InvokeVoidAsync("setDxDarkOverride", needsOverride);
+ }
+ catch (JSException)
+ {
+ // JS-Funktion noch nicht verfügbar – kein Circuit-Crash
+ }
}
private void ToggleTheme()
@@ -45,6 +80,6 @@
public void Dispose()
{
- ThemeState.OnChange -= StateHasChanged;
+ ThemeState.OnChange -= OnThemeChanged;
}
}
diff --git a/DbFirst.BlazorWebApp/Components/Routes.razor b/DbFirst.BlazorWebApp/Components/Routes.razor
index f7f43eb..2daf851 100644
--- a/DbFirst.BlazorWebApp/Components/Routes.razor
+++ b/DbFirst.BlazorWebApp/Components/Routes.razor
@@ -1,4 +1,5 @@
-@rendermode InteractiveServer
+@rendermode @(new InteractiveServerRenderMode(prerender: false))
+
diff --git a/DbFirst.BlazorWebApp/Services/ThemeState.cs b/DbFirst.BlazorWebApp/Services/ThemeState.cs
index 7b72b26..cd0eeb6 100644
--- a/DbFirst.BlazorWebApp/Services/ThemeState.cs
+++ b/DbFirst.BlazorWebApp/Services/ThemeState.cs
@@ -14,6 +14,16 @@ public class ThemeState
public bool IsDarkMode { get; private set; }
public string CurrentThemeName { get; private set; } = "Fluent";
+ ///
+ /// Themes die eine native DevExpress Dark-Variante besitzen:
+ /// - Fluent ? Themes.Fluent.Clone(ThemeMode.Dark), verwendet --DS-* Token-System
+ /// - BlazingBerry ? Themes.BlazingDark
+ /// Alle anderen Themes (Purple, OfficeWhite, BootstrapExternal) haben keine offizielle
+ /// Dark-Variante; dort übernehmen CSS-Overrides auf --dxbl-grid-* Variablen die Arbeit.
+ ///
+ public bool IsNativeDarkTheme => IsDarkMode &&
+ (CurrentThemeName == "Fluent" || CurrentThemeName == "BlazingBerry");
+
public static readonly List AvailableThemes = ["Fluent", "BlazingBerry", "Purple", "OfficeWhite", "BootstrapExternal"];
public event Action? OnChange;
@@ -45,13 +55,11 @@ public class ThemeState
});
themeChangeService.SetTheme(theme);
}
- else if (CurrentThemeName == "BlazingBerry") themeChangeService.SetTheme(Themes.BlazingBerry);
- else if (CurrentThemeName == "Purple") themeChangeService.SetTheme(Themes.Purple);
- else if (CurrentThemeName == "OfficeWhite") themeChangeService.SetTheme(Themes.OfficeWhite);
+ else if (CurrentThemeName == "BlazingBerry") themeChangeService.SetTheme(IsDarkMode ? Themes.BlazingDark : Themes.BlazingBerry);
+ else if (CurrentThemeName == "Purple") themeChangeService.SetTheme(Themes.Purple);
+ else if (CurrentThemeName == "OfficeWhite") themeChangeService.SetTheme(Themes.OfficeWhite);
else if (CurrentThemeName == "BootstrapExternal") themeChangeService.SetTheme(Themes.BootstrapExternal);
else
themeChangeService.SetTheme(Themes.Fluent);
-
- OnChange?.Invoke();
}
}
\ No newline at end of file
diff --git a/DbFirst.BlazorWebApp/appsettings.Development.json b/DbFirst.BlazorWebApp/appsettings.Development.json
index 702a28b..be563e8 100644
--- a/DbFirst.BlazorWebApp/appsettings.Development.json
+++ b/DbFirst.BlazorWebApp/appsettings.Development.json
@@ -5,5 +5,11 @@
"Microsoft.AspNetCore": "Warning"
}
},
- "ApiBaseUrl": "https://localhost:7204/"
+ "ApiBaseUrl": "https://localhost:7204/",
+ "BrowserLink": {
+ "Enabled": false
+ },
+ "DetailedErrors": true
}
+
+
diff --git a/DbFirst.BlazorWebApp/wwwroot/app.css b/DbFirst.BlazorWebApp/wwwroot/app.css
index a0da4df..37c7c6d 100644
--- a/DbFirst.BlazorWebApp/wwwroot/app.css
+++ b/DbFirst.BlazorWebApp/wwwroot/app.css
@@ -148,6 +148,105 @@ dxbl-grid tbody tr:nth-child(even) td {
background-color: var(--grid-stripe-bg) !important;
}
+/* ?? Dark-Mode-Overrides für nicht-native Themes ?????????????????????????????
+ Strategie: CSS-Custom-Properties werden von DevExpress DIREKT auf den
+ Komponenten-Elementen definiert (z. B. --dxbl-popup-bg:#fff auf .dxbl-modal).
+ Eine geerbte Variable aus html.dx-dark würde durch die direkte Zuweisung
+ überschrieben. Deshalb targeten wir exakt dieselben Elemente, aber mit einem
+ zusätzlichen Vorfahren-Selektor (html.dx-dark) für höhere Spezifizität:
+ html.dx-dark .dxbl-modal = (0,2,1) > .dxbl-modal = (0,1,0) ?
+ html.dx-dark wird per JS gesetzt, wenn IsDarkMode && !IsNativeDarkTheme.
+?? */
+
+/* Popup / Modal (CRUD-Dialoge) – Variablen-Quelle: .dxbl-modal */
+html.dx-dark .dxbl-modal {
+ --dxbl-popup-bg: #2d2d2d;
+ --dxbl-popup-color: #e8e8e8;
+ --dxbl-popup-border-color: #555;
+ --dxbl-popup-header-bg: #333;
+ --dxbl-popup-header-color: #e8e8e8;
+ --dxbl-popup-footer-bg: #333;
+ --dxbl-popup-footer-color: #e8e8e8;
+}
+
+/* Flyout (Column Chooser, Filter-Panel) – Variablen-Quelle: .dxbl-flyout */
+html.dx-dark .dxbl-flyout {
+ --dxbl-flyout-bg: #2d2d2d;
+ --dxbl-flyout-color: #e8e8e8;
+ --dxbl-flyout-border-color: #555;
+ --dxbl-flyout-header-bg: #333;
+ --dxbl-flyout-header-color: #e8e8e8;
+ --dxbl-flyout-footer-bg: #333;
+}
+
+/* Dropdown (ComboBox-Klappliste, Band-Dropdowns) – Quelle: .dxbl-dropdown */
+html.dx-dark .dxbl-dropdown,
+html.dx-dark .dxbl-itemlist-dropdown {
+ --dxbl-dropdown-bg: #2d2d2d;
+ --dxbl-dropdown-color: #e8e8e8;
+ --dxbl-dropdown-border-color: #555;
+ --dxbl-dropdown-header-bg: #333;
+ --dxbl-dropdown-footer-bg: #333;
+}
+
+/* Edit-Dropdown (ComboBox-Popup wenn als Modal gerendert) – Quelle: .dxbl-edit-dropdown */
+html.dx-dark .dxbl-edit-dropdown {
+ --dxbl-edit-dropdown-bg: #2d2d2d;
+ --dxbl-edit-dropdown-color: #e8e8e8;
+ --dxbl-edit-dropdown-border-color: #555;
+}
+
+/* ListBox (Einträge in Dropdowns) – Quelle: .dxbl-list-box */
+html.dx-dark .dxbl-list-box,
+html.dx-dark .dxbl-list-box-render-container {
+ --dxbl-list-box-bg: #2d2d2d;
+ --dxbl-list-box-color: #e8e8e8;
+ --dxbl-list-box-border-color: #555;
+ --dxbl-list-box-item-hover-bg: #3a3a3a;
+ --dxbl-list-box-item-hover-color: #e8e8e8;
+}
+
+/* TextEdit / ComboBox – Eingabefeld – Quelle: .dxbl-text-edit */
+html.dx-dark .dxbl-text-edit {
+ --dxbl-text-edit-bg: #2d2d2d;
+ --dxbl-text-edit-color: #e8e8e8;
+ --dxbl-text-edit-border-color: #555;
+ --dxbl-text-edit-btn-bg: #3a3a3a;
+ --dxbl-text-edit-btn-color: #e8e8e8;
+ --dxbl-text-edit-btn-hover-bg: #444;
+ --dxbl-text-edit-btn-hover-color: #e8e8e8;
+}
+
+/* Buttons */
+html.dx-dark .dxbl-btn {
+ --dxbl-btn-color: #e8e8e8;
+ --dxbl-btn-bg: #3a3a3a;
+ --dxbl-btn-border-color: #555;
+ --dxbl-btn-hover-bg: #444;
+ --dxbl-btn-hover-color: #e8e8e8;
+ --dxbl-btn-hover-border-color: #666;
+}
+
+/* FormLayout */
+html.dx-dark .dxbl-fl {
+ --dxbl-fl-caption-color: #bbb;
+ --dxbl-fl-group-bg: #242424;
+ --dxbl-fl-group-color: #e8e8e8;
+}
+
+/* Grid */
+html.dx-dark .dxbl-grid {
+ background-color: #242424;
+ color: #e8e8e8;
+ border-color: #444;
+}
+
+html.dx-dark .dxbl-grid > .dxbl-scroll-viewer,
+html.dx-dark .dxbl-grid > .dxbl-grid-top-panel {
+ background-color: #242424;
+ color: #e8e8e8;
+}
+
/* MassData-spezifisch */
.page-size-selector {
display: flex;
diff --git a/DbFirst.BlazorWebApp/wwwroot/js/size-manager.js b/DbFirst.BlazorWebApp/wwwroot/js/size-manager.js
index 3cd47e6..64d9a78 100644
--- a/DbFirst.BlazorWebApp/wwwroot/js/size-manager.js
+++ b/DbFirst.BlazorWebApp/wwwroot/js/size-manager.js
@@ -1,3 +1,4 @@
window.setSize = function (fontSize) {
document.documentElement.style.setProperty('--global-size', fontSize);
};
+