본문 바로가기
전산공부

WPF MVVM - ViewModel에서 View의 함수 호출하기

by 공펄양 2022. 7. 6.

MVVM  패턴을 사용하다 보면 컨트롤에 있는 함수를 호출해야 하는 경우가 많습니다.

ViewModel에서 View 컨트롤의 함수를 호출하기 위해서 사용하는 방법 중 하나인 Behavior입니다.

기본적인 이야기는 생략하고, Behavior 사용 부분만 기입하도록 하겠습니다.

 

버튼을 누르면 Window가 닫히는 간단한 프로젝트를 구성해 보겠습니다.

 

1. 프로젝트를 생성합니다.

기본적인 프로젝트 생성 방법은 아실거라고 생각하고 넘어갑니다.

 

2. Nuget을 설치합니다.

ReactiveUI.WPF

Microsoft.Xaml.Behaviors.Wpf

ReactiveUI는 아시겠지만, 데이터를 바인딩 하는데 있어서 구현해야 하는 번거로운 것들을 대신 해줍니다.

Microsoft.Xaml.Behaviors.Wpf로 Behavior를 구성해서 Control의 Action을 ViewModel의 Action과 연결해줍니다.

 

3. Behavior를 상속받아 ViewModel과 연결하는 클래스를 구성합니다.

using Microsoft.Xaml.Behaviors;
using System;
using System.Windows;

public class WindowBehavior : Behavior<Window>
{
    public Action CloseAction
    {
        get { return (Action)GetValue(CloseActionProperty); }
        set { SetValue(CloseActionProperty, value); }
    }

    public static readonly DependencyProperty CloseActionProperty =
    DependencyProperty.Register(nameof(CloseAction), typeof(Action), typeof(WindowBehavior), new PropertyMetadata(null));

    protected override void OnAttached()
    {
        SetCurrentValue(CloseActionProperty, (Action)AssociatedObject.Close);
        base.OnAttached();
    }
}

 

4. ViewModel에 바인딩 할 Command와 Action을 구현합니다.

public class MainWindowViewModel : ReactiveObject
{
    private Action _closeAction;
    public Action CloseAction
    {
        get => _closeAction;
        set => this.RaiseAndSetIfChanged(ref _closeAction, value);
    }

    public ReactiveCommand<Unit, Unit> ClickButtonCommand { get; set; }

    public MainWindowViewModel()
    {
        ClickButtonCommand = ReactiveCommand.Create(() => {
            CloseAction?.Invoke();
        });
    }
}

 

5. View에서 Window 내부에 Behavior를 넣어줍니다.

<Window xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
	xmlns:behaviors="clr-namespace:BehaviorsStudy.Behaviors"
    ...>
    <Button Command="{Binding ClickButtonCommand}" Grid.Column="1" Content="Close" />
	<i:Interaction.Behaviors>
        <behaviors:WindowBehavior CloseAction="{Binding CloseAction, Mode=OneWayToSource}" />
    </i:Interaction.Behaviors>
</Window>

 

 

 

 

 

반응형