Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wpf MVVM How to handle TextBox "paste event" in the ViewModel

I develop application with using MVVM pattern. I using MVVMLight library to do this. So if I need to handle TextBox TextChange event I write in XAML:

<I:EventTrigger EventName="TextChanged">
    <I:InvokeCommandAction Command="{Binding PropertyGridTextChange}"/>
</I:EventTrigger>

where PropertyGridTextChange is Command in ViewModel. But TextBox has no Paste event!

This solution only works if application don't use MVVM pattern, because you need to have link on TextBox.

<DataTemplate x:Key="StringTemplate">
    <TextBox Text="{Binding Value, ValidatesOnDataErrors=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    </TextBox>
</DataTemplate>

Important detail - TextBox placed within DataTemplate. I have no idea how can I handle "paste event". I want PasteCommand to be invoked when I paste text into TextBox. And I need that TextBox.Text or TextBox itself to be passed as parameter into PasteCommandMethod.

private RelayCommand<Object> _pasteCommand;
public RelayCommand<Object> PasteCommand
{
    get
    {
        return _pasteCommand ?? (_pasteCommand =
            new RelayCommand<Object>(PasteCommandMethod));
    }
}

private void PasteCommandMethod(Object obj)
{
} 
like image 796
monstr Avatar asked Feb 11 '23 00:02

monstr


1 Answers

I can suggest answer on my question.

Class-helper.

public class TextBoxPasteBehavior 
{
public static readonly DependencyProperty PasteCommandProperty =
    DependencyProperty.RegisterAttached(
        "PasteCommand",
        typeof(ICommand),
        typeof(TextBoxPasteBehavior),
        new FrameworkPropertyMetadata(PasteCommandChanged)
    );

public static ICommand GetPasteCommand(DependencyObject target)
{
    return (ICommand)target.GetValue(PasteCommandProperty);
}

public static void SetPasteCommand(DependencyObject target, ICommand value)
{
    target.SetValue(PasteCommandProperty, value);
}

static void PasteCommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    var textBox = (TextBox)sender;
    var newValue = (ICommand)e.NewValue;

    if (newValue != null)
        textBox.AddHandler(CommandManager.ExecutedEvent, new RoutedEventHandler(CommandExecuted), true);
    else
        textBox.RemoveHandler(CommandManager.ExecutedEvent, new RoutedEventHandler(CommandExecuted));

}

static void CommandExecuted(object sender, RoutedEventArgs e)
{
    if (((ExecutedRoutedEventArgs)e).Command != ApplicationCommands.Paste) return;

    var textBox = (TextBox)sender;
    var command = GetPasteCommand(textBox);

    if (command.CanExecute(null))
        command.Execute(textBox);
}
}

Using in XAML. In TextBox as attribute.

TextBoxPasteBehavior.PasteCommand="{Binding PropertyGridTextPasted}"

PropertyGridTextPasted - Command in the ViewModel.

like image 55
monstr Avatar answered Feb 13 '23 19:02

monstr