覆盖可编辑 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;
}