티스토리 뷰

반응형

2022.04.21 - [WPF .NET] - Microsoft.Toolkit.Mvvm을 이용한 간단한 프레임워크 part6 - 유효성 검사 추가

2022.03.11 - [WPF .NET] - Microsoft.Toolkit.Mvvm을 이용한 간단한 프레임워크 part5 - 금액 표시 컨트롤 만들기

2022.03.03 - [WPF .NET] - Microsoft.Toolkit.Mvvm을 이용한 간단한 프레임워크 part4 - LayerPopup 추가

2022.03.02 - [WPF .NET] - Microsoft.Toolkit.Mvvm을 이용한 간단한 프레임워크 part3 - Busy 화면 구현

2022.02.24 - [WPF .NET] - Microsoft.Toolkit.Mvvm을 이용한 간단한 프레임워크 part2 - Frame Navigation

 

Microsoft.Toolkit.Mvvm에 대한 몇번의 posting은 했었지만, 그 nuget pacakge를 이용해서 사용할 수 있는 프레임워크를 만드는 방법에 대해서는 설명을 드리지 않은 것 같아서 이번 기회에 실제 프로젝트에서도 사용 가능한 형태의 프레임워크를 만들어 보도록 하겠습니다.

 

이 프레임워크는 소형 프로젝트에서 사용하기 적당한 프레임워크입니다. 대형 프로젝트에서는 Prism 사용을 권장합니다.

1. WPF .NET 5.0 프로젝트 생성

프로젝트를 생성하는 방법에 대해서는 따로 설명드리지 않겠습니다.

2. Nuget package 추가

프로젝트 파일을 마우스 오른쪽으로 클릭하고, 컨텍스트 메뉴에서 Manage NuGet Packages...를 선택합니다.

 

1) mvvm toolkit으로 검색하시면 Microsoft.Toolkit.Mvvm 패키지를 찾으실 수 있습니다.

최신버전을 선택하신 후 Install 버튼을 눌러서 설치하시면 됩니다. 혹시 .NET 5.0 이전 버전의 .NET을 사용하신다면, 버전을 낮추면서 해당 .NET 버전을 지원하는 녀석을 찾아서 설치하시면 됩니다.

MVVM Toolkit에 대한 더 자세한 설명은 여기를 참고하시면 됩니다.

2) behavior로 검색해서 Microsoft.Xaml.Behaviors.Wpf 패키지를 설치합니다.

MVVM Pattern을 이용해서 개발을 하기 위해서 반드시 필요한 패키지이니 꼭 설치를 하셔야 합니다. Behavior와 InvokeCommandAction 등의 기능을 이용할 수 있습니다.

3) dependencyinjection으로 검색해서 Microsoft.Extensions.DependencyInjection 페키지를 설치합니다.

프로젝트에서 IoC를 이용하기 위해서 필요한 package입니다.

3. 폴더 정리

Views, ViewModels, 폴더를 생성하고, MainWindow.xaml을 Views 폴더로 이동시켜 줍니다.

MainWindow.xaml을 다른 폴더로 이동하면 App.xaml의 StartUri를 /Views/MainWindow.xaml로 변경해 주셔야 합니다.

4. IoC

Mvvm Toolkit의 IoC에 대한 자세한 설명은 여기를 참고하시기 바랍니다.

 

App.xaml.cs

아래와 같이 App.xaml.cs를 간단하게 작성해 줍니다.

IServiceProvider ConfigureServices() 내부에서는 애플리케이션에서 사용할 각종 서비스, 뷰모델들을 Injection하기 위해서 미리 등록하는 곳입니다.

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Windows;

namespace WpfFramework
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public App()
        {
            Services = ConfigureServices();
            this.InitializeComponent();
        }

        /// <summary>
        /// Gets the current <see cref="App"/> instance in use
        /// </summary>
        public new static App Current => (App)Application.Current;

        /// <summary>
        /// Gets the <see cref="IServiceProvider"/> instance to resolve application services.
        /// </summary>
        public IServiceProvider Services { get; }

        /// <summary>
        /// Configures the services for the application.
        /// </summary>
        private static IServiceProvider ConfigureServices()
        {
            var services = new ServiceCollection();


            return services.BuildServiceProvider();
        }
    }
}

5. ViewModelBase.cs

메인뷰모델을 추가하기 전에 ViewModelBase 클래스를 먼저 추가합니다. 이 ViewModelBase 클래스는 모든 뷰모델의 Base가 될 클래스이며, 나중에 필요한 기능을 추가해서 사용합니다. 가능하면 만들어서 사용하는 것이 나중을 위해서 좋습니다.

 

아직 특별한 기능이 필요 없기 때문에, Title 프로퍼티 한개만 추가했습니다.

using Microsoft.Toolkit.Mvvm.ComponentModel;

namespace WpfFramework.Bases
{
    /// <summary>
    /// 뷰모델 베이스
    /// </summary>
    public abstract class ViewModelBase : ObservableObject
    {
        private string _title;
        /// <summary>
        /// 타이틀
        /// </summary>
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

    }
}

6. MainViewModel.cs

MainWindow의 ViewModel로 처음에는 기본적인 내용들만 있습니다.

using WpfFramework.Bases;

namespace WpfFramework.ViewModels
{
    /// <summary>
    /// 메인 뷰모델 클래스
    /// </summary>
    public class MainViewModel : ViewModelBase
    {
        /// <summary>
        /// 생성자
        /// </summary>
        public MainViewModel()
        {
            Title = "Main View";
        }
    }
}

7. ViewModel을 IoC에 등록

App.xaml.cs -> ConfigureServices()에 MainViewModel을 추가합니다.

MainViewModel은 한번 생성되면, 애플리케이션이 종료되기 전까지 유지되기 때문에 AddTransient로 등록하면 됩니다.

            //ViewModel 등록
            services.AddTransient(typeof(MainViewModel));

8. 등록된 Type을 사용하기

MainWindow.xaml.cs의 생성자에 아래 코드를 추가해서 등록된 type을 인스턴스 시켜서 사용할 수 있습니다.

        public MainWindow()
        {
            InitializeComponent();
            DataContext = App.Current.Services.GetService(typeof(MainViewModel));
        }

9. MainWindow.xaml 수정

title를 ViewModel의 Title 프로퍼티를 바인딩하도록 수정했습니다. 그리고 DockPanel을 배치하고, 메뉴를 배치하고, Frame를 배치했습니다.

제가 만들려는 프레임워크에서는 Frame을 이용해서 각 Page를 네비게이션 시켜서 사용하게 될 것입니다. TabControl을 사용해서 여러개의 화면을 이동 할 수 있도록 하는 프레임워크는 여러분이 직접 만들어 보시기 바랍니다.

 

메뉴 Header에 _를 입력한 이유는 alt키를 이용해서 단축키로 접근하는 이름을 지정하기 위해서 입니다. alt+f를 눌러보시면 확인하실 수 있습니다.

<Window
    x:Class="WpfFramework.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfFramework"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="{Binding Title}"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Header="_New" />
                <MenuItem Header="_Open" />
                <MenuItem Header="_Save" />
                <Separator />
                <MenuItem Header="_Exit" />
            </MenuItem>
        </Menu>
        <Frame />
    </DockPanel>
</Window>

10. 실행 화면

프레임워크 만들기는 천천히 조금씩 진행하면서 올리도록 하겠습니다. 특히, Pull Request를 만들어서 올리고, Merge를 하지 않을 예정이기 때문에 원하는 Branch를 다운 받아서 확인하고 실행하실 수 있도록 만들 예정입니다.

11. 소스

kaki104/WpfFramework (github.com)

 

GitHub - kaki104/WpfFramework

Contribute to kaki104/WpfFramework development by creating an account on GitHub.

github.com

이 프레임워크에 넣었으면 하는 기능이 있으면 리플로 남겨주시면 확인하도록 하겠습니다.

반응형
댓글
  • 프로필사진 helpandplay 안녕하세요. 포스트를 보다가 궁금한 점이 있습니다.

    [MainViewModel은 한번 생성되면, 애플리케이션이 종료되기 전까지 유지되기 때문에 AddTransient로 등록하면 됩니다.]
    이 글이 정확히 와닿지 않는데요. 혹시 조금 더 부연설명을 해주실 수 있나요?

    시작부터 종료까지 어차피 1번만 생성될꺼니까 Transient로 생성해도 문제 없겠다 싶어서 Transient로 생성을 하신 건지 궁금합니다.
    2022.03.20 20:51
  • 프로필사진 Connor Park 네 생각하신 내용이 맞습니다.

    그렇치만, 만약, MainWindow를 여러개 생성할 수 있는 애플리케이션인데, 1개의 뷰모델만을 사용하고자 한다면, services.AddSingleton(typeof(MainViewModel)); 이렇게 싱글톤으로 뷰모델을 만들어주시고 사용하시면 됩니다.
    2022.03.20 22:19 신고
  • 프로필사진 helpandplay 답변 감사합니다. 정확히 이해했습니다. 2022.03.21 09:05
댓글쓰기 폼
반응형
Total
689,181
Today
227
Yesterday
434
«   2022/07   »
          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            
07-07 17:37
글 보관함