1

I have a custom ItemsControl just like that

public class MyControl : ItemsControl { }

My Template would something like

<Style TargetType="{x:Type local:MyControl}">
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBox Text="{Binding Text}" /> 
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

Now I want to act when either when ENTER or SPACE got pressed so I'd do something like this

<TextBox Text="{Binding Text}">
    <TextBox.InputBindings>
        <KeyBinding Key="Space" 
                    Command="{Binding KeyPressedCommand}" 
                    CommandParameter="{x:Static Key.Space}"/>
    </TextBox.InputBindings>
</TextBox>

But how do I bind it to my Control?

  • Where is the `TextBox` defined? You should probably handle your logic in the controll class instead of using key bindings in the view. – mm8 Mar 23 '20 at 14:08
  • What is the problem to put the snippet with `InputBindings` to the `TextBox` in the `DataTemplate`? – Rekshino Mar 24 '20 at 07:51

1 Answers1

1

One of ways to solve it is using MVVM pattern and RelayCommand class from tutorial.

RelayCommand.cs

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Func<object, bool> _canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter) => _canExecute == null || _canExecute(parameter);
    public void Execute(object parameter) => _execute(parameter);
}

Then you should set DataContext of your Window (or UserControl), it requred for resolving bindings in xaml.

One of ways doing it:

MainWindow.xaml

<Window.DataContext>
    <local:MainViewModel/>
</Window.DataContext>

Setup Text Property and KeyPressedCommand from "something like this" example in the MainViewModel class.

MainViewModel.cs

public class MainViewModel : INotifyPropertyChanged
{
    private bool _text;
    public bool Text
    {
        get => _text;
        set
        {
            _text = value;
            OnPropertyChanged(nameof(Text));
            // Text changed!
        }
    }
    public ICommand KeyPressedCommand => new RelayCommand(obj =>
    {
        if (obj is Key key) {
            // do something here with the 'key' provided by CommandParameter
        }
    });

    public MainViewModel()
    {
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
aepot
  • 4,558
  • 2
  • 12
  • 24