覆盖可编辑 WPF ComboBox 的 ApplicationCommands.Copy
Overriding ApplicationCommands.Copy for editable WPF ComboBox
我重写了一些控件 ApplicationCommands.Copy 并取得了成功,但无法弄清楚如何让它与 WPF 中的可编辑 ComboBox 一起工作。例如,TextBox 可以像这样正常工作:
var copyCommandBinding = new CommandBinding(ApplicationCommands.Copy, CopyToClipboardExecuted);
MyTextBox.CommandBindings.Add(copyCommandBinding); // Works as expected
当我尝试对可编辑的 ComboBox 执行相同操作时,它不起作用,即使我 return 对 CanExcute 为真:
var copyCommandBinding = new CommandBinding(ApplicationCommands.Copy, CopyToClipboardExecuted);
MyComboBox.CommandBindings.Add(copyCommandBinding); // Nothing happens
我通过添加 KeyUp 事件处理程序并测试 CTRL+C 来解决这个问题,但感觉这不是正确的解决方案:
public MyWindow()
{
MyComboBox.KeyUp += MyComboBox_KeyUp;
}
private void MyComboBox_KeyUp(object sender, KeyEventArgs e)
{
if (!Keyboard.IsKeyDown(Key.LeftCtrl) && !Keyboard.IsKeyDown(Key.RightCtrl)) return;
if (e.Key == Key.C) CopyToClipboardExecuted();
}
我知道在可编辑的 ComboBox 上添加 TextChanged 事件处理程序需要一些额外的工作来利用 TestBoxBase 的事件,所以我想知道是否有一些类似的技巧来获得 ApplicationCommands.Copy 支持相同的 TextBoxBase。我似乎找不到任何包含此详细信息的文档。
感谢任何猜测、帮助或提示,谢谢!
我的假设是正确的,进一步挖掘得到了答案。为此,要访问 ComboBox 的 TextBoxBase,您必须使用 Template.FindName() method. The documentation 表明这是可找到的,因为 "PART_EditableTextBox." 您还可以使用这个找到的参考来在 TextBoxBase 上设置事件处理程序。唯一的问题是您只能在控件呈现后这样做:
private void MyWindow_ContentRendered(object sender, EventArgs e)
{
// Intercept Copy at Window
CommandBinding copyCommandBinding = new CommandBinding(ApplicationCommands.Copy, CopyToClipboardExecuted);
CommandBindings.Add(copyCommandBinding);
// Intercept Copy within TextBox
MyTextBox.CommandBindings.Add(copyCommandBinding);
// Intercept Copy within ComboBox
TextBox comboTextBox = MyTextBox.Template.FindName("PART_EditableTextBox", MyTextBox) as TextBox;
comboTextBox.CommandBindings.Add(copyCommandBinding);
comboTextBox.TextChanged += MyComboBox_TextChanged;
}
我重写了一些控件 ApplicationCommands.Copy 并取得了成功,但无法弄清楚如何让它与 WPF 中的可编辑 ComboBox 一起工作。例如,TextBox 可以像这样正常工作:
var copyCommandBinding = new CommandBinding(ApplicationCommands.Copy, CopyToClipboardExecuted);
MyTextBox.CommandBindings.Add(copyCommandBinding); // Works as expected
当我尝试对可编辑的 ComboBox 执行相同操作时,它不起作用,即使我 return 对 CanExcute 为真:
var copyCommandBinding = new CommandBinding(ApplicationCommands.Copy, CopyToClipboardExecuted);
MyComboBox.CommandBindings.Add(copyCommandBinding); // Nothing happens
我通过添加 KeyUp 事件处理程序并测试 CTRL+C 来解决这个问题,但感觉这不是正确的解决方案:
public MyWindow()
{
MyComboBox.KeyUp += MyComboBox_KeyUp;
}
private void MyComboBox_KeyUp(object sender, KeyEventArgs e)
{
if (!Keyboard.IsKeyDown(Key.LeftCtrl) && !Keyboard.IsKeyDown(Key.RightCtrl)) return;
if (e.Key == Key.C) CopyToClipboardExecuted();
}
我知道在可编辑的 ComboBox 上添加 TextChanged 事件处理程序需要一些额外的工作来利用 TestBoxBase 的事件,所以我想知道是否有一些类似的技巧来获得 ApplicationCommands.Copy 支持相同的 TextBoxBase。我似乎找不到任何包含此详细信息的文档。
感谢任何猜测、帮助或提示,谢谢!
我的假设是正确的,进一步挖掘得到了答案。为此,要访问 ComboBox 的 TextBoxBase,您必须使用 Template.FindName() method. The documentation 表明这是可找到的,因为 "PART_EditableTextBox." 您还可以使用这个找到的参考来在 TextBoxBase 上设置事件处理程序。唯一的问题是您只能在控件呈现后这样做:
private void MyWindow_ContentRendered(object sender, EventArgs e)
{
// Intercept Copy at Window
CommandBinding copyCommandBinding = new CommandBinding(ApplicationCommands.Copy, CopyToClipboardExecuted);
CommandBindings.Add(copyCommandBinding);
// Intercept Copy within TextBox
MyTextBox.CommandBindings.Add(copyCommandBinding);
// Intercept Copy within ComboBox
TextBox comboTextBox = MyTextBox.Template.FindName("PART_EditableTextBox", MyTextBox) as TextBox;
comboTextBox.CommandBindings.Add(copyCommandBinding);
comboTextBox.TextChanged += MyComboBox_TextChanged;
}