WPF Icommand, 예제

doyeon kim·2025년 2월 5일

C#

목록 보기
12/13

✅ ICommand란

ICommand는 WPF에서 버튼 클릭 등의 UI 이벤트를 ViewModel에서 처리할 수 있도록 하는 인터페이스로
MVVM 패턴을 사용하면 Button.Click 같은 이벤트 핸들러를 직접 사용하지 않고, ICommand를 활용하여 UI와 로직을 분리할 수 있음

🔹 1. ICommand 인터페이스의 기본 구조

public interface ICommand
{
    bool CanExecute(object parameter); // 버튼 활성화 여부 결정
    void Execute(object parameter);   // 버튼 클릭 시 실행할 동작

    event EventHandler CanExecuteChanged; // CanExecute 상태 변경 이벤트
}

✅ ICommand를 사용하면 버튼 클릭 이벤트를 ViewModel에서 직접 처리 가능
✅ XAML에서 Command 바인딩을 활용하면 UI와 코드 숨김 파일을 분리할 수 있음

예시(현재시간 출력)

ViewModel

 public class InterfaceViewModel : INotifyPropertyChanged
    {
        private readonly IDateTime _dateTime;
        private string _currentTime = string.Empty;

        public event PropertyChangedEventHandler PropertyChanged;

        public InterfaceViewModel(IDateTime dateTime)
        {
            
            _dateTime = dateTime;
            
            OnTextChangedCommand = new RelayCommand(OnTextChanged);
        }


        public string CurrentTime
        {
            get { return _currentTime; }
            set
            {
                if (_currentTime != value)
                {
                    _currentTime = value;
                    OnPropertyChanged(nameof(CurrentTime));
                }
            }
        }

     
        public ICommand OnTextChangedCommand { get; }


        private void OnTextChanged()
        {
            CurrentTime = _dateTime.GetCurrentTime().ToString();
        }

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


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 bool CanExecute(object parameter)
        {
            return _canExecute == null || _canExecute();
        }

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

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

interface

 public interface IDateTime
    {
        // 인터페이스 생성하고 메서드 생성
        DateTime? GetCurrentTime();
    }

service

class DateTimeService : IDateTime
    {
        // 상속받은 IDateTime 에 선언된 메서드 구현
        public DateTime? GetCurrentTime()
        {
            return DateTime.Now;
        }
    }

작동원리

✅ OnPropertyChanged(propertyName)를 호출하면 바인딩된 UI 요소가 자동으로 갱신됨
✅ 의존성 주입(DI)을 통해 IDateTime 인터페이스를 받아옴
✅ IDateTime은 GetCurrentTime()을 제공하는 서비스로, 현재 시간을 반환하는 역할
✅ 생성자에서 OnTextChangedCommand를 RelayCommand로 초기화하여 버튼과 연결
✅ CurrentTime 값이 변경될 때 OnPropertyChanged(nameof(CurrentTime)) 호출 → UI 자동 업데이트
✅ XAML에서 Text="{Binding CurrentTime}"으로 바인딩 가능
✅ _dateTime.GetCurrentTime()을 호출하여 CurrentTime을 현재 시간으로 업데이트
✅ UI에서 CurrentTime을 바인딩한 TextBlock이 자동으로 업데이트됨

※ 다중 주석 : ctrl + k + c 해제 : ctrl + k + u

0개의 댓글