Prism에서의 전역 Command 세팅방법 - 모든 View의 Command를 한 커맨드로 실행시키고 싶을 때
https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/12-UsingCompositeCommands
코드는 이쪽에서 참조
https://github.com/2Bbear/WindowsProgrmaDevelop/tree/master/WPF/UsingMvvmPrismLibrary/12-UsingCompositeCommands
내가 만든 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public partial class App : PrismApplication { protected override Window CreateShell() { return Container.Resolve<MainWindow>(); } protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) { moduleCatalog.AddModule<ModuleA.ModuleAModule>(); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterSingleton<IApplicationCommands, ApplicationCommands>(); } } | cs |
기본 시작 윈도우를 MainWindow로 설정했고.
모듈을 사용하니 ConfigureModuleCatalog를 이용하여 모듈 카타로그에 ModuleA의 ModuleAModule을 추가했네요
RegisterTypes으로 컨테이너를 등록하였는데
containerRegistry에 ApplicationCommands를 등록했습니다. 이 부분은 잘 모르겠으니 나중에 자세히 알아보겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <Window x:Class="UsingCompositeCommands.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" Title="{Binding Title}" Height="350" Width="525"> <Window.Resources> <Style TargetType="TabItem"> <Setter Property="Header" Value="{Binding DataContext.Title}" /> </Style> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Button Content="Save" Margin="10" Command="{Binding ApplicationCommands.SaveCommand}"/> <TabControl Grid.Row="1" Margin="10" prism:RegionManager.RegionName="ContentRegion" /> </Grid> </Window> | cs |
일단 MainWindow의 XAML을 확인해보니 ViewModelLocator를 이용하여 ViewModel을 이용 하였음을 알 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class MainWindowViewModel : BindableBase { private string _title = "Prism Unity Application"; public string Title { get { return _title; } set { SetProperty(ref _title, value); } } private IApplicationCommands _applicationCommands; public IApplicationCommands ApplicationCommands { get { return _applicationCommands; } set { SetProperty(ref _applicationCommands, value); } } public MainWindowViewModel(IApplicationCommands applicationCommands) { ApplicationCommands = applicationCommands; } } } | cs |
MainWindow의 ViewModel을 확인하니 title 프로퍼티가 있고,
IApplicationCommands 라는 프로퍼티가 생겨있습니다.
MainWindowViewModel이 생성될때 applicationCommands를 받아와서 저장 하는 용도로 사용하려는 프로퍼티로 보입니다.
====================
다시 Mainwindow의 XMAL로 돌아가서
<TabControl Grid.Row="1" Margin="10" prism:RegionManager.RegionName="ContentRegion" />
탭 컨트롤에 리전이 걸려있는데.
ContentRegion은 MainWindow관련 코드에서는 찾아보질 못했습니다. 그럼 어디에 있는지 찾아보면 App에서 붙인 모듈 ModuleAModule에 정의되어 있을 겁니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class ModuleAModule : IModule { public void OnInitialized(IContainerProvider containerProvider) { var regionManager = containerProvider.Resolve<IRegionManager>(); IRegion region = regionManager.Regions["ContentRegion"]; var tabA = containerProvider.Resolve<TabView>(); SetTitle(tabA, "Tab A"); region.Add(tabA); var tabB = containerProvider.Resolve<TabView>(); SetTitle(tabB, "Tab B"); region.Add(tabB); var tabC = containerProvider.Resolve<TabView>(); SetTitle(tabC, "Tab C"); region.Add(tabC); } public void RegisterTypes(IContainerRegistry containerRegistry) { } void SetTitle(TabView tab, string title) { (tab.DataContext as TabViewModel).Title = title; } } | cs |
OnInitialized , 즉 모듈이 생성될 당시에 컨테이너 제공자로부터 regionManager를 받아옵니다.
해당 region에 ContentRegion이라는 등록명을 넣고
해당 View로 tabA, tabB, tabC 를 넣어놓습니다.
이 tab view들은 하나의 클래스 인데 TabView라는 유저컨트롤로 만들어져있습니다.
SetTitle 이라는 메소드는 Tabview형식을 받아 title을 변경하는 메소드입니다.
내용을 보면
TabView.DataContext는 TabViewModel 형식 일텐데. 즉 ViewLocator로 연결되어 있는 ViewModel이라는 것입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | public class TabViewModel : BindableBase { IApplicationCommands _applicationCommands; private string _title; public string Title { get { return _title; } set { SetProperty(ref _title, value); } } private bool _canUpdate = true; public bool CanUpdate { get { return _canUpdate; } set { SetProperty(ref _canUpdate, value); } } private string _updatedText; public string UpdateText { get { return _updatedText; } set { SetProperty(ref _updatedText, value); } } public DelegateCommand UpdateCommand { get; private set; } public TabViewModel(IApplicationCommands applicationCommands) { _applicationCommands = applicationCommands; UpdateCommand = new DelegateCommand(Update).ObservesCanExecute(() => CanUpdate); _applicationCommands.SaveCommand.RegisterCommand(UpdateCommand); } private void Update() { UpdateText = $"Updated: {DateTime.Now}"; } } | cs |
TabViewModel 을 열어보면 내부에 Title이라는 프로퍼티가 만들어져있는 것을 알 수 있습니다.
===========================
그런데, 이 내부 안에 DelegateCommand가 있는게 보입니다.
public DelegateCommand UpdateCommand { get; private set; }
UpdateCommand 가 어디에 연결되어 있는지 확인하니 Save Button에 연결되어 있음을 확인할 수 있습니다.
이제 TabViewModel로 만든 모든 tab은 버튼 클릭시 이 updataCommand가 실행되게 됩니다.
생성자를 다시 보면 applicationCommadns에 SaveCommand.Registercommand를 통해서 런타임으로 만들어진 DelegateCommand를 등록 할 수 있습니다.
이렇게 등록하게 될 경우 어떤 일이 일어나는 걸까요.
바로 전역으로 ApplicationCommand를 불러서 모든 버튼에 Command를 발생시킬 수 있게 됩니다.
그 코드는
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <Window x:Class="UsingCompositeCommands.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" Title="{Binding Title}" Height="350" Width="525"> <Window.Resources> <Style TargetType="TabItem"> <Setter Property="Header" Value="{Binding DataContext.Title}" /> </Style> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Button Content="Save" Margin="10" Command="{Binding ApplicationCommands.SaveCommand}"/> <TabControl Grid.Row="1" Margin="10" prism:RegionManager.RegionName="ContentRegion" /> </Grid> </Window> | cs |
MainWindow XAML에서 확인 할 수 있습니다.
최상단에 button이 있는데 Command로 ApplicationComands.SaveCommand를 호출하는 것을 볼 수 있습니다.
즉 응용프로그램 생성 당시 만들어지는 applicationCommand를 MainWindow에 저장하여 해당 윈도우에서 전역 applicationCommand에 접근하여 저장된 모든 Command를 실행시키는 것입니다.
'중단한 프로젝트 > WPF_PrismLibrary(추후진행)' 카테고리의 다른 글
Prism에서 DelegateCommand를 하는 방법 (0) | 2019.02.20 |
---|---|
Prism에서 CustomViewModel을 view에 붙이는 방법 (0) | 2019.02.19 |
Prism으로 어떻게 다른 모듈의 view를 호출하는가 (0) | 2019.02.19 |
Prism은 어떻게 모듈을 관리하는가 (0) | 2019.02.19 |
Prism은 어떻게 View를 다른 View로 변경하는가 (0) | 2019.02.19 |