[C# WPF] Behavior - InvokeCommandAction

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

WPF

목록 보기
10/22
post-custom-banner

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
안뇽하세용
post-custom-banner

2개의 댓글

comment-user-thumbnail
2024년 6월 23일

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

1개의 답글