본문 바로가기
WPF

WPF MVVM TextBox KeyDown Event

by leo21c 2021. 7. 20.

WPF로 MVVM 패턴을 이용해서 TextBox의 KeyDown 이벤트를 확인해서 검색이나 다른 기능을 실행 시키기 위해서 처리하는 방법을 검색해서 만들어 보았다.

 

프로젝트에 Notifier.cs와 DelegateCommnad.cs를 추가한다.

ViewModel.cs를 만들어 DataContext에 연결한다.

 

MainWindow.xaml에는 TextBox 하나를 추가했다.

<Window x:Class="Wpf_TextBox_KeyDown.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:Wpf_TextBox_KeyDown"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TextBox HorizontalAlignment="Left" Height="27" Margin="37,33,0,0" TextWrapping="Wrap" 
                 Text="{Binding InputData, UpdateSourceTrigger=PropertyChanged}"
                 VerticalAlignment="Top" Width="132">
            <TextBox.InputBindings>
                <KeyBinding Key="Enter" Command="{Binding KeyEnterCommand}" />
            </TextBox.InputBindings>
        </TextBox>
    </Grid>
</Window>

MainWindow.xaml.cs에서 DataContext 연결을 한다.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        this.DataContext = new MainViewModel();
    }
}

MainViewModel.cs는 Notifier.cs를 상속받는다.

public class Notifier : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
public class MainViewModel : Notifier
{
    public MainViewModel()
    {
        KeyEnterCommand = new DelegateCommand(onKeyEnterCommand);
    }

    private string _InputData;
    public string InputData { get { return _InputData; } set { _InputData = value; OnPropertyChanged("InputData"); } }

    public ICommand KeyEnterCommand { get; set; }

    public void onKeyEnterCommand()
    {
        MessageBox.Show(_InputData);
    }
}

TextBox의 Data는 InputData와 바인딩 하고 KeyBinding은 KeyEnterCommand와 바인딩해서 사용을 한다.

DelegateCommand는 위와 같이 구현하면 된다.

 

public class DelegateCommand : ICommand
{
    private readonly Func<bool> canExecute;
    private readonly Action execute;

    ///<summary> 
    ///Initializes a new instance of the DelegateCommand class. 
    ///</summary> 
    ///<param name="execute">indicate an execute function</param> 
    public DelegateCommand(Action execute) : this(execute, null)
    {
    }

    ///<summary> 
    ///Initializes a new instance of the DelegateCommand class. 
    ///</summary> 
    ///<param name="execute">execute function </param> 
    ///<param name="canExecute">can execute function</param> 
    public DelegateCommand(Action execute, Func<bool> canExecute)
    {
        this.execute = execute;
        this.canExecute = canExecute;
    }

    ///<summary> 
    ///can executes event handler 
    ///</summary> 
    public event EventHandler CanExecuteChanged;

    ///<summary> 
    ///implement of icommand can execute method 
    ///</summary> 
    ///<param name="o">parameter by default of icomand interface</param> 
    ///<returns>can execute or not</returns> 
    public bool CanExecute(object o)
    {
        if (this.canExecute == null)
        {
            return true;
        }
        return this.canExecute();
    }

    ///<summary> 
    ///implement of icommand interface execute method 
    ///</summary> 
    ///<param name="o">parameter by default of icomand interface</param> 
    public void Execute(object o)
    {
        this.execute();
    }

    ///<summary> 
    ///raise ca excute changed when property changed 
    ///</summary> 
    public void RaiseCanExecuteChanged()
    {
        if (this.CanExecuteChanged != null)
        {
            this.CanExecuteChanged(this, EventArgs.Empty);
        }
    }
}

 

프로그램을 실행하고 TextBox에 Text를 입력한 후 Enter를 누르면 메시지 박스가 표시된다.