Refactored OnThemeChanged in MainLayout.razor to use InvokeAsync for proper synchronization of UI updates and async logic, preventing threading issues. Also added a blank line after app.Run() in Program.cs (no functional impact).
87 lines
2.3 KiB
Plaintext
87 lines
2.3 KiB
Plaintext
@inherits LayoutComponentBase
|
||
@implements IDisposable
|
||
@inject ThemeState ThemeState
|
||
@inject IJSRuntime JS
|
||
|
||
<div class="page @(ThemeState.IsDarkMode ? "app-dark" : "app-light") @(ThemeState.IsNativeDarkTheme ? "native-dark" : "")">
|
||
<div class="sidebar">
|
||
<NavMenu />
|
||
</div>
|
||
|
||
<main>
|
||
<div class="top-row px-4">
|
||
<DxComboBox Data="@ThemeState.AvailableThemes"
|
||
Value="@ThemeState.CurrentThemeName"
|
||
ValueChanged="@((string t) => ThemeState.SetTheme(t))"
|
||
style="width: 130px;" />
|
||
<span style="margin-left: 12px;">
|
||
<DxButton Text="@(ThemeState.IsDarkMode ? "Dark Mode aus" : "Dark Mode an")"
|
||
Click="ToggleTheme" />
|
||
</span>
|
||
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
|
||
</div>
|
||
|
||
<article class="content px-4">
|
||
@Body
|
||
</article>
|
||
</main>
|
||
</div>
|
||
|
||
<div id="blazor-error-ui">
|
||
An unhandled error has occurred.
|
||
<a href="" class="reload">Reload</a>
|
||
<a class="dismiss">🗙</a>
|
||
</div>
|
||
|
||
@code {
|
||
private bool _isInteractive;
|
||
|
||
protected override void OnInitialized()
|
||
{
|
||
ThemeState.OnChange += OnThemeChanged;
|
||
}
|
||
|
||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||
{
|
||
if (firstRender)
|
||
{
|
||
_isInteractive = true;
|
||
}
|
||
await ApplyDxDarkOverrideAsync();
|
||
}
|
||
|
||
private void OnThemeChanged()
|
||
{
|
||
InvokeAsync(async () =>
|
||
{
|
||
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()
|
||
{
|
||
ThemeState.SetDarkMode(!ThemeState.IsDarkMode);
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
ThemeState.OnChange -= OnThemeChanged;
|
||
}
|
||
}
|