LazyRegion.WPF은 WPF (Windows Presentation Foundation) 라이브러리로, ContentControl의 내용이 바뀔 때 즉각적인 전환 대신 부드러운 애니메이션 효과를 제공합니다. 기존 ContentControl은 콘텐츠가 변경되면 화면이 즉시 바뀌지만, LazyRegion.WPF은 페이드, 슬라이드 등 다양한 애니메이션을 통해 자연스럽고 시각적으로 매력적인 전환을 구현합니다. 이 라이브러리는 코드 비하인드, MVVM, 그리고 RegionManager를 통한 동적 콘텐츠 관리 등 다양한 개발 환경에 최적화되어 있습니다.
주요 특징
애니메이션 전환 지원: 설정한 애니메이션 효과와 속도에 맞춰 콘텐츠를 자연스럽게 변경합니다. 다양한 전환 효과(예: Fade, SlideLeft, ZoomIn)를 지원합니다.
MVVM 친화적: ViewModel의 변경을 자동으로 감지하여 뷰를 전환합니다. 데이터 템플릿을 사용하여 ViewModel에 따라 다른 화면을 자동으로 표시할 수 있습니다.
코드 비하인드 친화적: 코드 비하인드에서 Content 속성 값을 직접 변경하더라도 동일한 애니메이션 효과가 적용됩니다.
RegionManager 지원: RegionManager를 통해 미리 지정된 영역(Region)에 동적으로 화면을 주입하거나 변경할 수 있어, 모듈화된 애플리케이션 개발에 유용합니다.
사용 예시
MVVM 친화적
LazyRegion.WPF은 CurrentViewModel 속성에 바인딩되어 ViewModel이 변경될 때마다 데이터 템플릿에 따라 다른 화면을 표시하고 애니메이션을 적용합니다.
App.xaml에서 LazyRegion.WPF을 활성화하고 뷰를 등록한 후, RegionManager를 통해 특정 영역(Region)에 원하는 뷰를 동적으로 로드할 수 있습니다.
// App.xaml.cs에서 DI 등록
serviceCollection.UseLazyRegion();
serviceCollection.AddLazyView<AControl>("a");
serviceCollection.AddLazyView<BControls>("b");
// RegionManager를 통해 "Root" 영역에 "a" 키를 가진 뷰를 로드
this._lazyRegionManager.NavigateAsync("Root", "a");
이처럼 LazyRegion은 WPF 애플리케이션의 사용자 경험을 향상시키는 데 효과적인 도구입니다.
앞으로
시간 나는 대로 데모 영상과 샘플 프로젝트도 공유하겠습니다.
궁금한 점이나 피드백은 댓글로 남겨주세요!
RegionControl에 상태 기반 화면 관리 기능(RegionState)이 새롭게 추가되었습니다.
이제 각 Region은 자동으로 Loading 및 Error 상태 화면을 처리할 수 있습니다.
주요 기능
지정된 시간 동안 표시되는 Loading 화면
설정된 시간이 지나도 해당 Region에 변화가 없을 경우 자동으로 표시되는 Error 화면
Error 상태 이후에도 ViewKey 변화 시 정상적으로 화면 전환 가능
이 기능을 통해 Region 단위의 상태 관리가 더욱 단순하고 직관적으로 개선되었습니다.
지정 된 시간 초과 시 에러 화면 노출
지정 된 내 시간 내 리전에 화면 전환
기대효과
기존에는 API 요청 전후로 Region.NavigateAsync()를 직접 호출하여 “로딩 화면 → 실제 화면”으로 전환해야 했습니다. RegionState 도입 후에는 이러한 제어 로직을 ViewModel에서 제거하고, Region 자체가 자동으로 로딩/에러 상태를 관리합니다.
Before
// ViewModel 내부
public async Task LoadAsync()
{
await _regionManager.NavigateAsync("MainRegion", "LoadingView");
var result = await _api.GetDataAsync();
if (result.IsSuccess)
await _regionManager.NavigateAsync("MainRegion", "DataView");
else
await _regionManager.NavigateAsync("MainRegion", "ErrorView");
}
After
// ViewModel 내부
public async Task LoadAsync()
{
var result = await _api.GetDataAsync();
if (result.IsSuccess)
await _regionManager.NavigateAsync("MainRegion", "DataView");
}
MAUI는 기본적으로 Page 기반의 네비게이션을 사용하기 때문에 LazyRegion.Maui의 사용이 다소 의문스러울 수 있습니다.
하지만 이런 경우가 있습니다.
이런 경우가 있을겁니다. Shell, TabbedPage 에서는 자유롭게 페이지를 생성하고 네비게이션할 수 있지만,
네비게이션 바 아이콘을 변형하는 등 자유도가 낮아 원하는 UI를 구현하기 어려울 때가 종종 있어, 이럴 때 LazyRegion.Maui를 고려할 수 있습니다.
LazyRegion 컨트롤 코드를 보면서 라우팅에 대해 많이 배우고 있습니다. 좋은 기능을 개발 해주셔서 감사드립니다. 이전에는 TabContent를 이용해 처리 하던 것에서 한계를 느껴서 Region으로 변경중입니다. 바꾸면서 각 View를 Singleton으로 등록 할 것인지에 대해서도 View별로 다른 전략이 필요 할 수도 있겠다는 생각이 드네요.
이 문제는 UseLazyRegion만 IServiceCollection의 확장 메서드로 노출하고, 인터페이스를 만들어 AddLazyView 같은 보조 기능들을 빌더 패턴처럼 인터페이스의 확장 메서드로 노출하는 식으로 해결할 수 있기는 해요.
public interface ILazyRegionBuilder
{
IServiceCollection Services { get; }
// 필요한 것이 있다면 추가적인 메서드나 속성도 정의 가능
}
public static class ServiceCollectionExtensions
{
extension(IServiceCollection services)
{
public ILazyRegionBuilder UseLazyRegion()
{
// 서비스 등록 등의 작업 코드는 여기에
return new LazyRegionBuilder(services);
}
}
private class LazyRegionBuilder(IServiceCollection services) : ILazyRegionBuilder
{
public IServiceCollection Services { get; } = services;
}
}
그리고 ILazyRegionBuilder에 대한 추가 기능은, 별도의 확장 메서드로 제공하는 거지요.
public static class LazyRegionBuilderExtensions
{
extension(ILazyRegionBuilder builder)
{
public ILazyRegionBuilder AddLazyView<TView>(string key)
{
// 추가 로직 구현
return builder;
}
}
}
이렇게 하면 메서드 체이닝 형식의 api를 제공하면서도 원하는 방식을 유도할 수 있어요.
다만 람다 방식의 장점도 분명히 있다고 생각해요. 스코프가 명확하고, 빌더의 생명 주기를 라이브러리에서 제어할 수 있습니다. UseLazyRegion 스코프 안에서 이루어질 설정을 하나의 작업 단위로 다룰 수 있는 거죠.
실제로 닷넷 플랫폼 확장 (Microsoft.Extensions.*로 시작하는)에서도 목적에 맞게 두 가지 방식을 함께 사용합니다.