티스토리 뷰
Prism Library를 사용하는 개발자를 위한 안내 Part5 - Region & ContentControl Region Navigation
kaki104 2022. 11. 25. 10:002022.11.30 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part6 - TabControl Region Navigation
2022.11.18 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part4 - Register Types
2022.11.15 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part3 - DelegateCommand
2022.10.28 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part2 - 프로젝트 구성 살펴 보기
2022.10.27 - [WPF .NET] - Prism Library를 사용하는 개발자를 위한 안내 Part1
1. Prism Library에서 Navigation 사용하기
Navigation이란 인터넷 브라우저에서 웹 페이지에서 링크를 클릭해서 다른 웹 페이지로 이동하고, Back key를 눌러서 이전 페이지로 돌아가는 일련의 과정을 이야기합니다.
WPF에서는 Frame이라는 컨트롤을 이용하면, Page.xaml들을 인터넷 브라우저에서 사용하는 것과 같이 Navigation 시키고, Navigation Back을 시킬 수 있습니다. 그런데, 이 컨트롤을 이용한 Navigation을 실무 프로젝트에서 사용하는 것은 약간 불편합니다.
Frame 컨트롤을 이용하여 Navigation하는 간단한 예제는 여기를 참고하시기 바랍니다.
Prism Library에서는 Region이라는 논리 영역을 지정하고, 그 영역 내부에서 Navigation 시킬 수 있는 기능을 제공합니다.
아래 그림을 보면 TabControl을 "Edit Region"이라는 이름으로 정의하고, 아래 코드를 실행하면 Test1View를 인스턴스 시켜서, "Edit Region" TabControl의 TabItem을 하나 추가하고, 그 곳에 Test1View를 넣은 후 활성화를 시켜줍니다.
RegionManager.RequestNavigate("Edit Region", "Test1View");
Prism Library에서 Region Navigation을 어떻게 사용하는지 좀더 자세하게 알아 보도록 하겠습니다.
2. Region을 정의 할 수 있는 컨트롤
Prism Library에는 Region을 정의할 수 있는 RegionAdapter가 3개 있습니다.. 그 외에 컨트롤에 Region을 정의하고 사용하려면, RegionAdapterBase 클래스를 상속 받은 Adapter 클래스를 생성해서 사용하면 되며, 추후 이 부분에 대해서 다루도록 하겠습니다.
아래 RegionAdapter는 특정 컨트롤에 Region을 정의하면 자동으로 적용됩니다.
- ContentControlRegionAdapter
- 컨트롤 : ContentControl과 ContentControl을 상속 받은 컨트롤
- 한번에 한개의 화면만을 보여줄 수 있습니다.
- Navigate, Back, Forward
- 뷰모델에 INavigationAware 인터페이스를 구현해서, 네비게이션 관련 처리를 할 수 있습니다.
- SelectorRegionAdapter
- 컨트롤 : Selector를 상속 받은 컨트롤 예) TabControl, ListBox
- Select가 가능 합니다.
- 뷰모델에 IActiveAware 인터페이스를 구현해서, 활성화 여부를 알 수 있습니다.
- ItemsControlRegionAdapter
- 컨트롤 : ItemsControl과 ItemsControl을 상속 받은 컨트롤
- Select없이 나열합니다.
3. ContentControl에 Region 사용하기
MainWindow.xaml
간단하게 아래와 같은 화면을 만들어 줍니다.
<Window
x:Class="PrismStep4.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/"
Title="{Binding Title}"
Width="525"
Height="350"
prism:ViewModelLocator.AutoWireViewModel="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button
Command="{Binding NavigationCommand}"
CommandParameter="Test1View"
Content="Test1View" />
<Button
Command="{Binding NavigationCommand}"
CommandParameter="Test2View"
Content="Test2View" />
<Button
Command="{Binding NavigationCommand}"
CommandParameter="Back"
Content="Back" />
</StackPanel>
<ContentControl Grid.Row="1" prism:RegionManager.RegionName="ContentRegion" />
</Grid>
</Window>
MainWindowViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using System.Windows.Input;
namespace PrismStep4.ViewModels
{
public class MainWindowViewModel : BindableBase
{
private string _title = "Prism Application";
/// <summary>
/// Region관리자
/// </summary>
private readonly IRegionManager _regionManager;
/// <summary>
/// 타이틀
/// </summary>
public string Title
{
get => _title;
set => SetProperty(ref _title, value);
}
/// <summary>
/// 네비게이션 커맨드
/// </summary>
public ICommand NavigationCommand { get; set; }
/// <summary>
/// 기본 생성자
/// </summary>
public MainWindowViewModel()
{
NavigationCommand = new DelegateCommand<string>(OnNavigation);
}
/// <summary>
/// 런타임 생성자
/// </summary>
/// <param name="regionManager"></param>
public MainWindowViewModel(IRegionManager regionManager)
: this()
{
//IRegionManager를 Injection 받아서 사용하기 위해 _regionManager에 연결합니다.
_regionManager = regionManager;
}
/// <summary>
/// NavigationCommand의 실행 메서드
/// </summary>
/// <param name="para"></param>
private void OnNavigation(string para)
{
switch (para)
{
//Back이란 문자열이 들어오면..
case "Back":
{
//Back을 구현하기 위해서 ContentRegion의 Journal을 가져오고, 뒤로가기가 가능한지 확인 후 실행
IRegionNavigationJournal journal = _regionManager.Regions["ContentRegion"]
.NavigationService.Journal;
if (journal.CanGoBack)
{
journal.GoBack();
}
}
break;
//그외 일반 문자열이 들어오면
default:
//ContentRegion에 para가 지정하는 화면으로 네비게이트 해라
_regionManager.RequestNavigate("ContentRegion", para);
break;
}
}
}
}
그리고, 간단한 Test1View와 Test2View를 추가했습니다.
가장 중요한 네비게이션 가능한 화면 등록작업
App.xaml.cs
using Prism.Ioc;
using PrismStep4.Views;
using System.Windows;
namespace PrismStep4
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
//네비게이션할 화면 등록
containerRegistry.RegisterForNavigation<Test1View>();
containerRegistry.RegisterForNavigation<Test2View>();
}
}
}
실행
Test1View 버튼 클릭
Test2View 버튼 클릭
Back 버튼 클릭
Back 버튼 다시 클릭해도 더 이상 뒤로갈 수 없기 때문에 이동하지 않습니다.
4. INavigationAware를 이용해서 이동 상황 처리하기
Test1View.xaml
<UserControl
x:Class="PrismStep4.Views.Test1View"
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">
<Grid>
<ListBox
HorizontalAlignment="Center"
VerticalAlignment="Center"
ItemsSource="{Binding Messages}" />
</Grid>
</UserControl>
Test1ViewModel.cs
뷰모델에 INavigationAware 인터페이스를 구현하면, OnNavigatedTo, IsNavigationTarget, OnNavigatedFrom 메서드들이 추가됩니다.
네비게이트가될 때 실제로 어떻게 동작되는지 바로 알 수 있게 화면을 구성했습니다.
using Prism.Mvvm;
using Prism.Regions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace PrismStep4.ViewModels
{
public class Test1ViewModel : BindableBase, INavigationAware
{
public string Header { get; set; }
private IList<string> _messages = new ObservableCollection<string>();
/// <summary>
/// 메시지 목록
/// </summary>
public IList<string> Messages
{
get => _messages;
set => SetProperty(ref _messages, value);
}
public Test1ViewModel()
{
Header = GetType().Name;
Messages.Add(Header);
}
/// <summary>
/// 네비게이트 To
/// </summary>
/// <param name="navigationContext"></param>
public void OnNavigatedTo(NavigationContext navigationContext)
{
Messages.Add($"{GetType().Name} OnNavigatedTo");
}
/// <summary>
/// 네비게이트 가능 여부
/// </summary>
/// <param name="navigationContext"></param>
/// <returns></returns>
public bool IsNavigationTarget(NavigationContext navigationContext)
{
return true;
}
/// <summary>
/// 네비게이트 From
/// </summary>
/// <param name="navigationContext"></param>
public void OnNavigatedFrom(NavigationContext navigationContext)
{
Messages.Add($"{GetType().Name} OnNavigatedFrom");
}
}
}
실행 후 Test1View 클릭
Test2View 클릭
Back 버튼 클릭
Test2View 버튼을 클릭했을 때 OnNavigatedFrom이 실행되었다는 것을 알 수 있습니다. 물론 눈으로 확인을 할 수는 없었지만, 기록이 남아있으니 확인은 가능합니다. 그리고, Back으로 왔다고 하더라도, OnNavigatedTo 메서드가 호출되는 것을 알 수 있습니다.
5. 소스
WpfTest/PrismStep4 at master · kaki104/WpfTest (github.com)
'WPF .NET' 카테고리의 다른 글
Prism Library를 사용하는 개발자를 위한 안내 Part7 - Create RegionAdapter (0) | 2022.12.06 |
---|---|
Prism Library를 사용하는 개발자를 위한 안내 Part6 - TabControl Region Navigation (0) | 2022.11.30 |
Prism Library를 사용하는 개발자를 위한 안내 Part4 - Register Types (1) | 2022.11.18 |
Prism Library를 사용하는 개발자를 위한 안내 Part3 - DelegateCommand (0) | 2022.11.15 |
Prism Library를 사용하는 개발자를 위한 안내 Part2 - 프로젝트 구성 살펴 보기 (2) | 2022.10.28 |
- Total
- Today
- Yesterday
- dotNETconf
- .net 5.0
- uno-platform
- #Windows Template Studio
- Behavior
- Bot Framework
- Windows 10
- Microsoft
- kiosk
- windows 11
- Visual Studio 2022
- Build 2016
- LINQ
- WPF
- Always Encrypted
- ComboBox
- #MVVM
- Cross-platform
- MVVM
- .net
- PRISM
- #uwp
- visual studio 2019
- XAML
- #prism
- C#
- uno platform
- IOT
- UWP
- ef core
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |