안녕하세요, 반나무입니다.
이번 예제는 CompositeCommand를 사용하는 방법을 안내합니다.
CompositeCommand는 해당 Command를 통해 다른 ViewModel들의 DelegateCommand를 동시에 사용한다고 생각하면 됩니다.
한 개의 DelegateCommand라도 CanExcute = false일 경우 CompositeCommd의 CanExcute는 false가 됩니다.
설정창을 모듈화 한다면 전체 저장 같은 거에 사용하면 딱 좋을 듯합니다.
프로젝트 구조
먼저 프로젝트 구조를 살펴보겠습니다.
.Core가 들어간 프로젝트가 있어 처음에는 당황할 수 있습니다.
.Core로 이름을 지은 프로젝트는 해당 프로그램에서 전반적으로 사용되는 기능들이 들어있는 프로젝트라고 생각하면 됩니다.
- ModuleA : Shell에서 사용하기 위한 Module
- UsingCompositeCommands : 프로그램의 기본이 되는 Shell
- UsingCompositeCommands.Core : 프로그램 전반적으로 사용되는 기능이 들어가는 프로젝트
UsingCompositeCommands
Save버튼의 Command를 ApplicationCommands.SaveCommand로 설정합니다.
<Button Content="Save" Margin="10" Command="{Binding ApplicationCommands.SaveCommand}"/>
ApplicationCommand는 UsingCompositeCommands.Core 프로젝트에 있습니다.
App.xaml.cs에서 Module 등록 및 UsingCompositeCommand.Core에 있는 interface와 class를 싱글톤으로 등록합니다.
// App.xaml.cs
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
moduleCatalog.AddModule<ModuleA.ModuleAModule>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IApplicationCommands, ApplicationCommands>();
}
UsingCompositeCommand.Core
프로그램 내부에서 다양한 프로젝트들이 IApplicationCommand를 Prism 싱글톤으로 받아 사용하고 있습니다.
그렇기 때문에 .Core 프로젝트에 해당 파일을 생성하고 사용합니다.
// ApplicationCommands.cs
// UsingCompositeCommands에서 사용한 interface
public interface IApplicationCommands
{
CompositeCommand SaveCommand { get; }
}
public class ApplicationCommands : IApplicationCommands
{
private CompositeCommand _saveCommand = new CompositeCommand();
public CompositeCommand SaveCommand
{
get { return _saveCommand; }
}
}
ModuleA
TabView를 Region에 추가하면서 ViewModel을 3번 만들어 각각 연결합니다.
MainWindow에서 TabControl로 Region을 사용했기 때문에 별다른 작업 없이 Tab이 3개 추가됩니다.
// ModuleAModule.cs
public void OnInitialized(IContainerProvider containerProvider)
{
var regionManager = containerProvider.Resolve<IRegionManager>();
IRegion region = regionManager.Regions["ContentRegion"];
// Region에 TabView추가 -> ViewModel 인스턴스 생성
var tabA = containerProvider.Resolve<TabView>();
SetTitle(tabA, "Tab A");
region.Add(tabA);
// Region에 TabView추가 -> ViewModel 인스턴스 생성
var tabB = containerProvider.Resolve<TabView>();
SetTitle(tabB, "Tab B");
region.Add(tabB);
// Region에 TabView추가 -> ViewModel 인스턴스 생성
var tabC = containerProvider.Resolve<TabView>();
SetTitle(tabC, "Tab C");
region.Add(tabC);
}
ViewModel에서 각 DelegateCommand를 IApplicationCommands의 SaveCommand에 등록합니다.
// TabViewModel.cs
private bool _canUpdate = true;
public bool CanUpdate
{
get { return _canUpdate; }
set { SetProperty(ref _canUpdate, value); }
}
public DelegateCommand UpdateCommand { get; private set; }
// 3번 생성됨 -> SaveCommand에 각 ViewModel의 UpdateCommand가 연결됨
public TabViewModel(IApplicationCommands applicationCommands)
{
// DI
_applicationCommands = applicationCommands;
// DelegateCommand 초기화
UpdateCommand = new DelegateCommand(Update).ObservesCanExecute(() => CanUpdate);
// 한번에 제어하기 위해 Command를 등록한다.
// CanUpdate가 하나라도 false면 SaveCommand는 false가 된다.
_applicationCommands.SaveCommand.RegisterCommand(UpdateCommand);
}
private void Update()
{
UpdateText = $"Updated: {DateTime.Now}";
}
CompositeCommand를 F12로 타고 들어가면 RegisterCommand의 반대인 UnregisterCommand도 있기 때문에 해당 기능이 중간에 필요하지 않게 된다면 등록된 Command를 해제할 수도 있습니다.
'C# > Prism' 카테고리의 다른 글
[C# - Prism] 프리즘 예제 14 - UsingEventAggregator (0) | 2023.08.14 |
---|---|
[C# - Prism] 프리즘 예제 13 - IActiveAwareCommands (0) | 2023.08.08 |
[C# - Prism] 프리즘 예제 11 - UsingDelegateCommand (0) | 2023.08.05 |
[C# - Prism] 프리즘 예제 10 - CustomRegistrations (0) | 2023.07.26 |
[C# - Prism] 프리즘 예제 09 - ChangeConvention (0) | 2023.07.25 |
3년차 WPF 개발자입니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!