본문 바로가기

c#

wpf MVVM ICommand 버튼 비활성화 활성화

wpf의 mvvm 패턴을 활용한 버튼 활성화 비활성화 로직을 만들어 보겠습니다.

우선 MVVM패턴이기 때문에 view viewmodel 로 구분하겠습니다.

  • view
<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>

        <Button Command="{Binding ButtonCommand}"  CommandParameter="{Binding ElementName=cboA,Path=SelectedItem}"  Content="Button" HorizontalAlignment="Center" Margin="0,217,0,0" VerticalAlignment="Top" Height="51" Width="224" RenderTransformOrigin="0.324,1.336"/>
        <ComboBox Name="cboA" ItemsSource ="{Binding MainList}" HorizontalAlignment="Center" Margin="0,125,0,0" VerticalAlignment="Top" Width="120"/>

    </Grid>
</Window>

디자인 MainWindow.xaml

  • viewModel
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;

namespace WpfApp1
{
    class MainVM
    {
        //데이터가 들어갈 생성자
        public ObservableCollection<string> MainList { get; set; } = new ObservableCollection<string>();

        //버튼 command 바인딩 객체
        public Relaycommand ButtonCommand {get; set;}


        //데이터 할당
        public MainVM()
        {
            MainList = new ObservableCollection<string>()
            {
                 "1번"
                ,"2번"
                ,"3번"
            };

           
            ButtonCommand = new Relaycommand(ShowMessage, ButtonEnable);

        }

        // 버튼클릭시 실행되는 로직
        public void ShowMessage(object param) 
        {
            Console.WriteLine("123123");

        }

        //버튼이 비활성화 되는 조건
        public bool ButtonEnable(object param)
        {
            if ((string)param == "1번")
                return false;

            return true;

        }
    }
}

 

  • ICommand 상속 클래스
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;

namespace WpfApp1
{
    class Relaycommand :ICommand
    {
         Action<object> _execute;
         Predicate<object> _canExecute;
         
         public Relaycommand (Action<object> execute, Predicate<object> canExecute)
         {
             _execute = execute;
             _canExecute = canExecute;
         }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        
		//파라미터에서 특별한 값이 없으면 항상 true로 반환(항상 활성화)
        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute(parameter);
        }
		//넘겨받은 메서드 실행
        public void Execute(object parameter)
        {
            _execute.Invoke(parameter);
        }

    }
}

 

실행 결과

아래 로직에 맞게 1번이면 false이므로 버튼이 비활성화됨

public bool ButtonEnable(object param)
        {
            if ((string)param == "1번")
                return false;

            return true;

        }