반응형
해당 포스팅은 개인적으로 C# WPF를 공부하면서 익힌 내용을 기억에 남기기 위한 작업의 일환으로 작성된 글로서
일부 내용에 오류가 있을 수도 있으니 참고하시기 바랍니다.

 

 

C#WPF에서 MVVM패턴으로 
프로그래밍 할때 DataContext
에 대해 자세히
알아보자.

 

 

반응형
내용 요약

 

C# WPF에서 MVVM 패턴을 사용할 때, View와 ViewModel 간의 DataContext 설정은 매우 중요한 부분이다. MVVM(Model-View-ViewModel) 패턴은 UI와 비즈니스 로직을 분리하여 유지보수성과 테스트 용이성을 높이는 데 도움을 주는데, 이 글에서는 DataContext를 설정하는 다양한 방법에 대해 설명하도록 하겠다.

 

목차
1. 기본적인 DataContext 설정
2. 코드 비하인드에서 DataContext 설정
3. Dependency Injection을 통한 DataContext 설정
4. ViewModelLocator 패턴
5. 구조체와 클래스의 DataContext 설정
6. ViewModel의 속성 변경 알림
7. ViewModel의 생성자 매개변수
8. ViewModel의 명령
9. XAML에서 명령 바인딩

 

1. 기본적인 DataContext 설정

 

WPF에서 View와 ViewModel 간의 연결은 주로 DataContext 속성을 통해 이루어진다. DataContext는 View가 바인딩할 데이터의 소스를 지정한다. 가장 간단한 방법은 XAML에서 직접 설정하는 것이다.

 

<예제 1: XAML에서 DataContext 설정>

<Window x:Class="MyApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MyViewModel />
    </Window.DataContext>
    <Grid>
        <TextBox Text="{Binding MyProperty}" />
    </Grid>
</Window>

위의 예제에서 MyViewModel은 ViewModel 클래스이며, MyProperty는 ViewModel의 속성입니다. 이 방법은 View가 로드될 때 ViewModel의 인스턴스가 생성되고, DataContext가 설정된다.

 

2. 코드 비하인드에서 DataContext 설정

 

XAML에서 DataContext를 설정하는 대신, 코드 비하인드에서 설정할 수도 있다. 이 방법은 ViewModel의 인스턴스를 동적으로 생성해야 할 때 유용하다.

 

<예제 2: 코드 비하인드에서 DataContext 설정>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new MyViewModel();
    }
}

이 경우, MainWindow의 생성자에서 DataContext를 설정한다. 이 방법은 ViewModel의 생성자에 매개변수를 전달해야 할 때 유용하다.

 

3. Dependency Injection을 통한 DataContext 설정

 

Dependency Injection(DI)을 사용하여 ViewModel을 주입하는 방법도 있다.

이 방법은 특히 대규모 애플리케이션에서 유용하다.

 

<예제 3: DI를 통한 DataContext 설정>

public partial class MainWindow : Window
{
    private readonly IMyViewModel _viewModel;

    public MainWindow(IMyViewModel viewModel)
    {
        InitializeComponent();
        _viewModel = viewModel;
        this.DataContext = _viewModel;
    }
}

이 예제에서는 IMyViewModel 인터페이스를 통해 ViewModel을 주입받는다. DI 컨테이너를 사용하여 ViewModel의 인스턴스를 관리할 수 있다.

 

4. ViewModelLocator 패턴

 

ViewModelLocator 패턴을 사용하면 XAML에서 ViewModel을 쉽게 바인딩할 수 있다. 이 패턴은 ViewModel을 자동으로 찾고 설정하는 데 도움을 준다.

 

<예제 4: ViewModelLocator 설정>

public class ViewModelLocator
{
    public MyViewModel MyViewModel => new MyViewModel();
}

 

XAML에서 ViewModelLocator를 사용하여 DataContext를 설정할 수 있다.

<Window x:Class="MyApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MyApp"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding MyViewModel, Source={StaticResource ViewModelLocator}}">
    <Grid>
        <TextBox Text="{Binding MyProperty}" />
    </Grid>
</Window>

 

 

5. 구조체와 클래스의 DataContext 설정

 

MVVM 패턴에서 ViewModel은 일반적으로 클래스 형태로 구현된다. 그러나 구조체를 사용할 수도 있다. 구조체는 값 타입이므로, 바인딩 시 주의가 필요하다.

 

<예제 5: 구조체를 ViewModel로 사용>

public struct MyViewModel
{
    public string MyProperty { get; set; }
}

 

구조체를 사용할 경우, 바인딩이 제대로 작동하지 않을 수 있다. 이는 구조체가 값 타입이기 때문에, 바인딩 시 변경 사항이 반영되지 않기 때문이다. 따라서, ViewModel은 클래스 형태로 구현하는 것이 좋다.

 

6. ViewModel의 속성 변경 알림

 

ViewModel의 속성이 변경될 때 UI에 알리기 위해 INotifyPropertyChanged 인터페이스를 구현해야 한다.

 

<예제 6: INotifyPropertyChanged 구현>

public class MyViewModel : INotifyPropertyChanged
{
    private string _myProperty;
    public string MyProperty
    {
        get => _myProperty;
        set
        {
            if (_myProperty != value)
            {
                _myProperty = value;
                OnPropertyChanged(nameof(MyProperty));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

이렇게 하면 MyProperty가 변경될 때 UI가 자동으로 업데이트됩니다.

 

7. ViewModel의 생성자 매개변수

 

ViewModel의 생성자에 매개변수를 전달하여 초기화할 수 있다. 이 경우, ViewModel을 생성할 때 필요한 데이터를 전달할 수 있다.

 

<예제 7: 생성자 매개변수 사용>

public class MyViewModel
{
    public MyViewModel(string initialValue)
    {
        MyProperty = initialValue;
    }

    public string MyProperty { get; set; }
}

이 경우, ViewModel을 생성할 때 초기값을 전달해야 한다.

8. ViewModel의 명령

 

MVVM 패턴에서는 UI의 동작을 ViewModel의 명령으로 처리한다. ICommand 인터페이스를 구현하여 명령을 정의할 수 있다.

 

<예제 8: ICommand 구현>

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Predicate<object> _canExecute;

    public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter) => _canExecute == null || _canExecute(parameter);

    public void Execute(object parameter) => _execute(parameter);
}

 

이제 ViewModel에서 명령을 정의할 수 있습니다.

public class MyViewModel : INotifyPropertyChanged
{
    public ICommand MyCommand { get; }

    public MyViewModel()
    {
        MyCommand = new RelayCommand(ExecuteMyCommand);
    }

    private void ExecuteMyCommand(object parameter)
    {
        // 명령 실행 로직
    }
}

 

9. XAML에서 명령 바인딩

 

XAML에서 명령을 바인딩하여 UI와 ViewModel 간의 상호작용을 구현할 수 있다.

 

<예제 9: XAML에서 명령 바인딩>

<Button Command="{Binding MyCommand}" Content="Click Me" />

이렇게 하면 버튼 클릭 시 ViewModel의 MyCommand가 실행된다

 


결론

 

WPF에서 MVVM 패턴을 사용할 때 View와 ViewModel 간의 DataContext 설정은 매우 중요하다. 다양한 방법으로 DataContext를 설정할 수 있으며, 각 방법은 특정 상황에 따라 유용하게 사용될 수 있다. ViewModel은 일반적으로 클래스 형태로 구현하며, INotifyPropertyChanged를 통해 UI와의 데이터 바인딩을 관리한다. 명령을 사용하여 UI의 동작을 ViewModel에서 처리할 수 있으며, XAML에서 쉽게 바인딩할 수 있다.

 

이러한 원칙을 따르면 WPF 애플리케이션을 보다 구조적이고 유지보수하기 쉽게 만들 수 있습니다. 따라서, MVVM 패턴을 잘 활용하여 효율적인 WPF 애플리케이션을 개발하시기 바랍니다.

반응형

+ Recent posts