개요
.net MAUI 환경에서 Scheduler 관련 App 을 직접 만들어서 사용 중인데
이떄 Syncfusion 컨트롤을 사용해서 개발하였습니다.
.NET, Xamarin, JavaScript, Angular UI components | Syncfusion
그동안 DevExpress 를 많이 사용했었기 때문에 DevExpress 사용을 고려해 보았으나 MAUI 컨트롤의 경우 WinUI 플랫폼을 지원하지 않습니다.
Android 와 iOS 만 지원한다고 합니다.
윈도우와 안드로이드 플랫폼에서 모두 동작하는 App 이 필요한 상황이라 한번도 사용해보지 않았지만 Syncfusion 컨트롤로 개발하게 되었습니다.
게다가 Syncfusion 의 경우 Visual Studio 처럼 Community 버전이 있어서 이 기회에 사용해 보게 되었습니다.
Scheduler 디자인을 Syncfusion MAUI Control 을 사용해서 개발해서 사용하던 도중에 Blazor 컨트롤도 궁금해서 살펴보게 되었는데
개인적인 호불호로 Scheduler 컨트롤이 MAUI 보다 Blazor 환경으로 나온 디자인이 좀 더 좋아 보여서 기존에 Maui 로 작성된 Scheduler UI 만 Blazor 로 대체하기로 하였습니다.
UI 뿐만 아니라 기능적인 부분도 좀 더 나은 상황입니다.
그래서 다음과 같이 Scheduler UI 만 BlazorWebView 컨트롤을 사용해서 일부 수정하기로 하였습니다.

테마를 동기화 할 수 있는 간단한 코드만 추출해서 구현한 샘플 소스에 대한 설명입니다.
MAUI 테마
MAUI 의 경우 테마를 설정할 수가 있습니다.
App 에서 시스템에 설정된 테마를 그대로 사용하거나, 시스템과 별개로 App 내에서 테마에 따라 디자인을 다르게 지정할 수 있습니다.
Syncfusion Blazor 테마
Syncfusion Blazor 의 경우 빌트인 테마를 지원합니다.
MAUI 의 경우 Dark Mode, Light Mode 를 지원하고 있어서
빌트인 테마 중에 bootstrap5 와 bootstrap5-dark 를 사용해서 맞춰주기로 하였습니다.
테마 동기화
MAUI 에서 테마가 변경될 때 BlazorWebView 도 동일하게 테마를 수정하기 위해 Javascript 를 호출해서 구현하기로 하였습니다.
MAUI 테마 변경 이벤트
Respond to system theme changes – .NET MAUI | Microsoft Learn 링크에서 설명한 이벤트를 사용해서 테마 변경에 대한 이벤트를 등록합니다.
App.xaml.cs 코드는 다음과 같습니다.
using MauiApp1.ViewModel;
using Syncfusion.Licensing;
namespace MauiApp1
{
public partial class App : Application
{
public App()
{
// todo : Register Syncfusion license
SyncfusionLicenseProvider.RegisterLicense("");
InitializeComponent();
MainPage = new HybridPage();
Application.Current.RequestedThemeChanged += async (s, e) =>
{
await UpdateAppShellInfo();
};
}
async Task UpdateAppShellInfo()
{
var page = Application.Current.MainPage as HybridPage;
if (page is not null)
{
var vm = page.BindingContext as HybridPageViewModel;
if (vm is not null)
{
await vm.UpdateAppShellInfo();
}
}
}
}
}
MainPageViewModel.cs 의 코드는 다음과 같습니다.
ThemeCommand 와 App.xaml.cs 에서
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MauiApp1.Services;
namespace MauiApp1.ViewModel
{
public partial class HybridPageViewModel : ObservableObject
{
readonly CascadingAppState _cascadingAppState;
public HybridPageViewModel(CascadingAppState cascadingAppState)
{
_cascadingAppState = cascadingAppState;
}
public string ThemeInfo
{
get { return $"System : {Application.Current?.PlatformAppTheme}, App : {Application.Current?.UserAppTheme}"; }
}
public bool IsDefault
{
get { return Application.Current?.UserAppTheme == AppTheme.Unspecified; }
}
public bool IsDark
{
get { return Application.Current?.UserAppTheme == AppTheme.Dark; }
}
public bool IsLight
{
get { return Application.Current?.UserAppTheme == AppTheme.Light; }
}
[RelayCommand]
async Task Theme(object? parameter)
{
await Application.Current.Dispatcher.DispatchAsync(async () =>
{
AppTheme? appTheme = (AppTheme)Enum.Parse(typeof(AppTheme), parameter.ToString());
if (appTheme is not null && Application.Current is not null)
{
Application.Current.UserAppTheme = appTheme.Value;
await _cascadingAppState.ToggleTheme();
}
});
}
public async Task UpdateAppShellInfo()
{
await Application.Current.Dispatcher.DispatchAsync(async () =>
{
OnPropertyChanged(nameof(ThemeInfo));
OnPropertyChanged(nameof(IsDefault));
OnPropertyChanged(nameof(IsDark));
OnPropertyChanged(nameof(IsLight));
});
}
}
}
그리고, 위 소스에서 CascadingAppState Service의 ToggleTheme 메서드를 호출하고 있습니다.
CascadingAppState.cs 의 코드는 다음과 같습니다.
테마 변경 이벤트가 포함되어 있습니다.
namespace MauiApp1.Services
{
public class CascadingAppState
{
public CascadingAppState()
{
}
public async Task ToggleTheme()
{
if (OnToggleTheme != null)
{
await OnToggleTheme.Invoke();
}
}
public event Func<Task>? OnToggleTheme;
}
}
Razor 페이지 소스에서 해당 이벤트를 등록합니다.
Scheduler.razor 의 코드 일부를 보면 다음과 같습니다.
OnInitializedAsync 메서드에서 해당 이벤트를 등록하고
이벤트가 호출된 경우 자바 스크립트를 호출하고 있습니다.
@code {
protected override async Task OnInitializedAsync()
{
await ToggleTheme();
_cascadingAppState.OnToggleTheme += async () =>
{
await ToggleTheme();
};
}
async Task ToggleTheme()
{
await InvokeAsync(async () =>
{
var isDark = (Application.Current?.UserAppTheme == AppTheme.Unspecified ? Application.Current.PlatformAppTheme : Application.Current?.UserAppTheme) == AppTheme.Dark;
await JS.ToggleTheme(isDark ? "bootstrap5-dark" : "bootstrap5");
StateHasChanged();
});
}
}
Syncfusion Blazor 테마 변경
Index.html 의 코드 일부를 보면 다음과 같습니다.
Syncfusion Blazor 테마를 변경하는 코드가 포함되어 있습니다.
<script>
function ToggleTheme(themeName) {
$('#themeLink').attr('href', `_content/Syncfusion.Blazor.Themes/${themeName}.css`);
}
</script>
스크린샷
상단의 테마 정보는 현재 시스템의 테마 정보와 App 에서 설정한 테마 정보를 표시하고 있습니다.
테마 변경 버튼의 경우 System 은 시스템 테마를 그대로 사용한다는 의미이며 Dark, Light 테마로 각각 변경하는 기능 버튼 입니다.


Github
해당 예제의 소스 코드는 다음 Github repository 를 참조하시면 됩니다.
0 Comments