• 포스트
  • 도구
  • 작업
  • 포스트
  • 도구
  • 작업
로그인회원가입

© 2005 kaisa.co.kr. All Rights Reserved.

소개개인정보처리방침7083620@hanmail.net
← 목록으로
2023-06-28

WPF와 XAML·MVVM 시작하기

WPF와 XAML·MVVM 시작하기

요약: XAML로 화면을 그리고, DataContext로 ViewModel을 붙여 화면과 로직을 나눈다.


1. 언제 WPF인가

WPF(Windows Presentation Foundation)는 .NET으로 Windows 데스크톱 UI를 만드는 프레임워크다. 화면은 XAML(마크업)로 선언하고, 동작은 C#으로 둔다.

WinForms는 코드에서 컨트롤을 직접 만지는 비중이 크다. WPF는 데이터 바인딩이 기본이라, 화면과 상태를 분리하기 쉽다. 대상이 Windows이고 .NET을 쓰는 내부 도구·클라이언트라면 WPF가 맞다. 웹·크로스플랫폼은 다른 스택을 고른다.

항목 역할
XAML 컨트롤 트리와 바인딩을 선언한다
C# 계산·명령·서비스 호출
MVVM View / ViewModel / Model 세 층
DataContext 이 화면이 바라보는 데이터 소스

실무 기본선: .NET 8/9 + WPF + MVVM + CommunityToolkit.Mvvm.


2. 핵심 개념

MVVM(Model-View-ViewModel)은 화면 코드와 비즈니스 상태를 나누는 패턴이다.

층 한 줄
View .xaml. 컨트롤과 {Binding}. 가능하면 코드비하인드에 로직을 두지 않는다
ViewModel 화면이 보여줄 값과 명령. UI 타입(Button, Window)을 참조하지 않는다
Model 엔티티·DTO. UI를 모른다
DataContext View가 바인딩할 객체. 보통 ViewModel 인스턴스

코드비하인드(MainWindow.xaml.cs)의 Click 핸들러에 저장 로직을 넣으면 테스트가 창을 띄워야 한다. 명령은 ViewModel의 ICommand로 올린다. 3편에서 다룬다.


3. 생성

dotnet new wpf -n MyApp -f net9.0
cd MyApp
dotnet add package CommunityToolkit.Mvvm
dotnet run

폴더 감각:

App.xaml
App.xaml.cs
Views/MainWindow.xaml
Views/MainWindow.xaml.cs
ViewModels/MainViewModel.cs
Models/
Services/

템플릿 기본은 MainWindow가 프로젝트 루트에 있다. 규모가 생기면 Views/로 옮기고 App.xaml의 StartupUri를 맞춘다.


4. 동작하는 예: 제목 바인딩

ViewModels/MainViewModel.cs:

using CommunityToolkit.Mvvm.ComponentModel;

namespace MyApp.ViewModels;

public partial class MainViewModel : ObservableObject
{
    [ObservableProperty]
    private string title = "Hello WPF";
}

ObservableObject + [ObservableProperty]는 속성 변경 시 UI에 “이 값이 바뀌었다”고 알리는 코드를 생성한다. 직접 INotifyPropertyChanged(속성 변경 알림)를 적어도 된다. 툴킷이 반복을 줄인다.

Views/MainWindow.xaml:

<Window x:Class="MyApp.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:MyApp.ViewModels"
        Title="MyApp" Height="240" Width="400">
  <Window.DataContext>
    <vm:MainViewModel />
  </Window.DataContext>
  <StackPanel Margin="16">
    <TextBlock Text="{Binding Title}" FontSize="20" />
    <TextBox Text="{Binding Title, UpdateSourceTrigger=PropertyChanged}" Margin="0,8,0,0" />
  </StackPanel>
</Window>

TextBox를 바꾸면 Title이 바뀌고 TextBlock이 따라간다. DataContext가 ViewModel이므로 {Binding Title}은 MainViewModel.Title이다.

Views/MainWindow.xaml.cs는 생성자 InitializeComponent()만 둔다.

using System.Windows;

namespace MyApp.Views;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

App.xaml:

<Application x:Class="MyApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="Views/MainWindow.xaml">
</Application>

XAML에서 ViewModel을 new하는 방식은 작은 앱에 충분하다. DI 컨테이너로 주입하는 방식은 서비스가 늘 때 검토한다.


5. 코드비하인드와 경계

허용에 가까운 것: 포커스 이동, 패스워드 박스처럼 바인딩이 약한 컨트롤 접착.

피한다: 파일 저장, 메시지 박스 직접 호출, HTTP. 저장은 ViewModel 명령, 대화상자는 서비스(5편).

리소스·스타일은 창마다 복사하지 않고 App.xaml 또는 ResourceDictionary로 뺀다. 4편.


6. 주의 / 흔한 실수

  • DataContext를 안 넣고 {Binding Title}. 출력은 비고, 출력창에 바인딩 오류가 난다. Visual Studio 출력 창을 본다.
  • ViewModel에서 MessageBox.Show. View가 테스트에 딸려 온다. 인터페이스로 감싼다.
  • 코드비하인드에서 컨트롤 이름으로 값을 읽기. txtName.Text는 MVVM이 아니다. 바인딩한다.
  • partial class 이름·네임스페이스가 XAML x:Class와 다름. 빌드가 실패한다.
  • .NET Framework 전용 WPF 템플릿으로 신규 시작. 신규는 SDK 스타일 + net8.0-windows / net9.0-windows다.

정리

WPF 시작은 컨트롤 암기가 아니다. XAML + DataContext + ViewModel 경계를 먼저 고정한다.

  • 화면 → XAML
  • 이 화면의 데이터 소스 → DataContext = ViewModel
  • 로직 → ViewModel (창 타입 없이)

연습

  1. dotnet new wpf 후 위 ViewModel을 붙여 TextBox와 TextBlock이 같은 Title을 쓰는지 확인한다.
  2. Subtitle 속성을 추가하고 두 번째 TextBlock에 바인딩한다.
  3. StartupUri를 Views/MainWindow.xaml로 옮긴 뒤 앱이 켜지는지 확인한다.

댓글

0

아직 댓글이 없습니다. 첫 댓글을 남겨보세요.

다음 글데이터 바인딩과 ObservableCollection
← 목록으로