[C# WPF] Behavior - InvokeCommandAction

우롱밀크티당도70·2023년 9월 18일
0

WPF

목록 보기
10/22

1. 배경

코드 비하인드가 아닌 MVVM 패턴을 지키며 컨트롤의 이벤트를 사용하는 방법
https://velog.io/@yu_oolong/C-WPF-Button을-눌러-Frame에-Page-띄우기-2 와 같은 솔루션에서 진행


2. 개발환경

  • VisualStudio 2022

3. 내용

3-1. NuGet 패키지 관리에서 Microsoft.Xaml.Behaviors.Wpf 다운로드

3-2. ICommand를 상속 받는 RelayCommand.cs 작성

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace PackagingSystem.Commands
{
    public class RelayCommand : ICommand
    {
        private readonly Action _execute;
        private readonly Func<bool> _canExecute;

        public RelayCommand(Action execute, Func<bool> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

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

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

    public class RelayCommand<T> : ICommand
    {
        readonly Action<T> _execute = null;
        readonly Predicate<T> _canExecute = null;

        public RelayCommand(Action<T> execute, Predicate<T> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute?.Invoke((T)parameter) ?? true;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            _execute((T)parameter);
        }
    }
}

3-3. Page1.xaml이 로드 될 시 동작하는 Behavior를 ViewModel에 작성

  • (Page1ViewModel.cs)
    BaseViewModel을 상속 받는다.
using PackagingSystem.Commands;
using PackagingSystem.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace PracticeProject.ViewModels
{
    internal class Page1ViewModel : BaseViewModel
    {
        public ICommand Page1LoadedCommand { get; set; }

        public Page1ViewModel() 
        {
            Page1LoadedCommand = new RelayCommand(Page1Loaded);
        }

        public void Page1Loaded()
        {
            MessageBox.Show("Page Loaded");
        }
    }
}

3-4. Page1.xaml에 namespace 추가하고 DataContext 작성

  • (Page1.xaml)
<Page x:Class="PracticeProject.Views.Page1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:PracticeProject.Views"
      xmlns:vm="clr-namespace:PracticeProject.ViewModels"
      xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
      mc:Ignorable="d" 
      d:DesignHeight="450" d:DesignWidth="800"
      Title="Page1" Background="Gray">

    <Page.DataContext>
        <vm:Page1ViewModel />
    </Page.DataContext>

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding Page1LoadedCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>

    <Grid>
        
    </Grid>
</Page>

4. 결과

앞서 Menu1을 누르면 Page1이 로드되게 했었는데 Behavior 작성을 추가하여 Page1이 로드 되기 직전에 MessageBox가 호출된다.

MessageBox의 확인 버튼을 누르면 Page1이 로드 된다.


5. 참조

Behavior

Loaded 이벤트

profile
안뇽하세용

2개의 댓글

comment-user-thumbnail
2024년 6월 23일

"3-3. Page1.xaml이 로드 될 시 동작하는 Behavior를 ViewModel에 작성"
커멘드를 작성 하시고, behavior 인터렉션으로 command 를 호출하신거 같아요
behavior 작성은 class 에 behavior 를 상속받아 작성하고 인터렉션시 behavior 클래스로 연결하여 , OnAttach() 와 OnDetaching() 을 이용하여 구현하는걸로 알고 있어요~

1개의 답글