You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF中MVVM模式下TextBox的DataObject.Pasting事件处理失效问题

问题解决:MVVM下绑定TextBox的DataObject.Pasting事件

原始问题

尝试在MVVM模式下,将ViewModel中的TextBoxPasting方法绑定到TextBox的DataObject.Pasting事件,使用Microsoft.Xaml.Behaviors库,但代码无法正常运行。

原始View代码

<TextBox Text="{Binding StartNumber, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"  FontSize="16" Height="27" Margin="10"/>
<behaviours:Interaction.Triggers >
    <behaviours:EventTrigger EventName="DataObject.Pasting">
        <behaviours:InvokeCommandAction x:Name="DataObjectPastingCommand" Command="{Binding DataObjectPastingCommand}" PassEventArgsToCommand="True"/>
    </behaviours:EventTrigger>
</behaviours:Interaction.Triggers>

原始ViewModel代码

public class MechanicViewModel : ViewModelBase, IMechanicViewModel
{
    private static readonly Regex _regex = new Regex("[^0-9.-]+");

    public MechanicViewModel()
    {
        DataObjectPastingCommand = new DelegateCommand<DataObjectPastingEventArgs>(TextBoxPasting);
    }

    public DelegateCommand<DataObjectPastingEventArgs> DataObjectPastingCommand { get; private set; }

    private static bool IsTextAllowed(string text)
    {
        return !_regex.IsMatch(text);
    }

    private void TextBoxPasting(DataObjectPastingEventArgs e)
    {
        if (e.DataObject.GetDataPresent(typeof(string)))
        {
            string text = (string)e.DataObject.GetData(typeof(string));
            if (!IsTextAllowed(text))
            {
                e.CancelCommand();
            }
        }
        else
        {
            e.CancelCommand();
        }
    }
}

错误分析

  1. 触发器未关联到TextBox:Interaction.Triggers是TextBox的附加属性,必须作为TextBox的子元素存在,否则无法将事件触发器绑定到目标TextBox。
  2. 附加事件写法错误:DataObject.Pasting是附加事件,直接在EventName中写DataObject.Pasting无法被正确识别,需要通过RoutedEvent属性指定,并引入对应命名空间。

修正后的代码

修正后的View代码

首先在XAML根元素添加DataObject的命名空间:

xmlns:data="clr-namespace:System.Windows;assembly=PresentationCore"
xmlns:behaviours="http://schemas.microsoft.com/xaml/behaviors"

然后调整TextBox和触发器的结构:

<TextBox Text="{Binding StartNumber, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"  
         FontSize="16" Height="27" Margin="10">
    <behaviours:Interaction.Triggers>
        <!-- 使用RoutedEvent指定附加事件 -->
        <behaviours:EventTrigger RoutedEvent="data:DataObject.Pasting">
            <behaviours:InvokeCommandAction Command="{Binding DataObjectPastingCommand}" 
                                            PassEventArgsToCommand="True"/>
        </behaviours:EventTrigger>
    </behaviours:Interaction.Triggers>
</TextBox>

修正后的ViewModel代码(确保命令定义正确)

如果使用Prism的DelegateCommand,需确保已引用Prism.Commands命名空间;如果是自定义实现,需保证泛型参数和事件参数匹配:

using Prism.Commands;
using System.Text.RegularExpressions;
using System.Windows;

public class MechanicViewModel : ViewModelBase, IMechanicViewModel
{
    private static readonly Regex _regex = new Regex("[^0-9.-]+");

    public MechanicViewModel()
    {
        DataObjectPastingCommand = new DelegateCommand<DataObjectPastingEventArgs>(TextBoxPasting);
    }

    public DelegateCommand<DataObjectPastingEventArgs> DataObjectPastingCommand { get; private set; }

    private static bool IsTextAllowed(string text)
    {
        return !_regex.IsMatch(text);
    }

    private void TextBoxPasting(DataObjectPastingEventArgs e)
    {
        if (e.DataObject.GetDataPresent(typeof(string)))
        {
            string text = (string)e.DataObject.GetData(typeof(string));
            if (!IsTextAllowed(text))
            {
                e.CancelCommand();
            }
        }
        else
        {
            e.CancelCommand();
        }
    }
}

额外注意事项

  • 确保ViewModel已正确设置为View的DataContext,否则命令绑定会失效。
  • 如果未使用Prism,可替换为自己实现的ICommand子类,只要支持带参数的命令执行即可。

内容的提问来源于stack exchange,提问作者user23516519

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:35:26