我正在使用InputManager检查控件的更改是由用户还是代码完成。这工作正常,除非用户使用上下文菜单进行剪切/复制/粘贴。如果用户在文本框中执行ctrl + v,InputManager会正确地通知它。但是,如果粘贴是从文本框的上下文菜单中完成的,则InputManager不会触发PreNotifyInput或PostNotifyInput事件。有人知道为什么或者如何检测这些用户操作?以下是一个工作示例。由于PreNotifyInput从不触发,所以用户在上面的文本框中使用剪切/复制/粘贴菜单时,下面的文本块永远不会更新。InputManager忽略从菜单启动时的剪切/复制/粘贴
XAML:
<Window x:Class="InputMgrDemo.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<StackPanel>
<TextBox TextChanged="TextBox_TextChanged" />
<TextBlock Name="_text" />
</StackPanel>
</Window>
后面的代码:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace InputMgrDemo
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
InputManager.Current.PreNotifyInput += ((sender, e) => _userInput = true);
InputManager.Current.PostNotifyInput += ((sender, args) => _userInput = false);
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (_userInput)
{
_text.Text = (sender as TextBox).Text;
}
}
private bool _userInput;
}
}
感谢您的(一如既往)详细的答案。它帮助我理解了这个问题。我很好奇,你怎么知道命令是通过调度器回调完成的? – 2010-06-14 16:51:01
在TextChanged事件中设置断点,然后查看调用堆栈。 TextChanged由TextBoxBase调用,由数据绑定代码调用,该代码由MenuItem单击处理代码调用,该代码由Dispatcher调用。由于MenuItem点击处理代码由Dispatcher调用,因此您知道MenuItem使用了调度程序回调。 – 2010-06-14 17:29:11
您需要禁用“Just My Code”并显示所有堆栈帧才能看到此内容。我建议你总是这样做 - 通过WPF的堆栈跟踪可以提供有关事情如何工作的有价值的线索。 – 2010-06-14 17:30:04