.net MAUI 테마와 syncfusion blazor(with BlazorWebView) 테마 동기화 예제

Published Sep 22, 2023 | Updated Feb 2, 2024 | 0 comments

개요

.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 를 지원하고 있어서
빌트인 테마 중에 bootstrap5bootstrap5-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 를 참조하시면 됩니다.

TAG INFORMATION

Learn more on this topic

Related Blog Posts

Join in the conversation

Leave a Comment

0 Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

무료 온라인 전광판

전광판

텍스트를 입력하고 텍스트 효과 및 배경효과 를 변경해서 전체화면으로 표시할 수 있는 전광판 용도로 사용하실 수 있습니다. 각종 스포츠 및 공연 관람시 응원 용도로 사용이 가능합니다.

Carousel

여러개의 슬라이드를 추가하여 프레젠테이션 및 이미지 슬라이드 용도로 사용하실 수 있습니다. 브라우저가 포함된 IT 기기로 큰 모니터에 연결하여 매장 내 공지사항 및 메뉴소개를 이미지로 표시할 수 있습니다.

Pin It on Pinterest

Shares
Share This

Share This

Share this post with your friends!

Shares