Wpf MVVM How to handle TextBox “paste event” in the ViewModel

百般思念 提交于 2019-12-07 19:11:55

问题


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)
{
} 

回答1:


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.




回答2:


I've been struggling with this kind of problem too in recent days. My first approach would be to have a property in the VM that is bound to the text box (which I am sure you already have). Then bind an ICommand to an event to handle the on paste event:

            xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="RowEditEnding">
                <i:InvokeCommandAction Command="{Binding DocRowEdit}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>

you need to define the namespace in the proper part of the XAML code, and then put the interaction triggers in as part of the textbox definition. Here I am capturing the RowEditEnding event to do some stuff similar to what you are attempting.

The command binding is another piece, let me know if you need more information on how that needs to be set up.



来源:https://stackoverflow.com/questions/28346652/wpf-mvvm-how-to-handle-textbox-paste-event-in-the-viewmodel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!