【问题标题】:WPF: Execute a Command Binding in a search field when pressing the enter buttonWPF:按下回车按钮时在搜索字段中执行命令绑定
【发布时间】:2010-12-07 22:30:25
【问题描述】:

我的 WPF 应用程序中有一个搜索字段,其中包含一个包含命令绑定的搜索按钮。这很好用,但是当在键盘上按下回车键时,如何对文本字段使用相同的命令绑定?我所看到的示例都是使用带有 KeyDown 事件处理程序的 Code behind。是否有一种聪明的方法可以使这项工作仅适用于 xaml 和命令绑定?

【问题讨论】:

    标签: c# wpf xaml commandbinding


    【解决方案1】:

    Prism 参考实现包含您所追求的实现。

    基本步骤是:

    • 创建一个静态类 EnterKey
    • 在 EnterKey 上注册了 ICommand 类型的附加属性“Command”
    • 在 EnterKey 上注册了 EnterKeyCommandBehavior 类型的附加属性“EnterKeyCommandBehavior”
    • 当“Command”的值发生变化时,将“EnterKeyCommandBehavior”作为 EnterKeyCommandBehavior 的新实例附加到控件,并将 ICommand 分配给行为的 Command 属性。
      • 如果行为已附加,请使用现有实例
    • EnterKeyCommandBehavior 接受构造函数中的 UIElement 并附加到 PreviewKeyDown(或 KeyDown,如果您想保持 Silverlight 兼容)。
    • 在事件处理程序中,如果键为 Enter,则执行 ICommand(如果 CanExecute 为 true)。

    这使您可以像这样使用行为:

    <TextBox prefix:EnterKey.Command="{Binding Path=SearchCommand}" />
    

    【讨论】:

      【解决方案2】:

      您可以使用按钮的 IsDefault 属性:

          <Button Command="SearchCommand" IsDefault="{Binding ElementName=SearchTextBox,
                                                     Path=IsKeyboardFocused}">
               Search!
         </Button>
      

      【讨论】:

      • 谢谢,简单又干净。效果很好!
      • 没有按钮怎么办?
      • 这在我第一次按 Enter 时有效。我继续编辑搜索并按回车键,它不执行搜索。当我按下回车键时,我必须手动返回搜索控件以使其执行另一个搜索。
      • 没关系——我是个白痴。我忘了在 TextBox 上添加 UpdateSourceTrigger=PropertyChanged :D
      【解决方案3】:

      仅当您已经将按钮绑定到命令时,接受的答案才有效。

      为避免此限制,请使用 TextBox.InputBindings:

      <TextBox.InputBindings>
          <KeyBinding Key="Enter" Command="{Binding Path=MyCommand}"></KeyBinding>
      </TextBox.InputBindings>
      

      【讨论】:

      • 我还必须更改 TextBox.Text 绑定上的 UpdateSourceTrigger 才能使其正常工作。更多详情,请查看Capturing the Enter key in a TextBox
      • 这应该是公认的答案。它工作得很好很干净,因为接受的答案有点hack。
      【解决方案4】:

      我尝试了 Greg Samson 的 TextBox.Inputs 解决方案,但收到一个错误消息,提示我只能通过依赖属性绑定到 textinputs。 最后我找到了下一个解决方案。

      创建一个名为 CommandReference 的类,如下所示:

      public class CommandReference : Freezable, ICommand
      {
          public CommandReference()
          {
              //
          }
      
          public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(CommandReference), new PropertyMetadata(new PropertyChangedCallback(OnCommandChanged)));
      
          public ICommand Command
          {
              get { return (ICommand)GetValue(CommandProperty); }
              set { SetValue(CommandProperty, value); }
          }
      
          #region ICommand Members
      
          public bool CanExecute(object parameter)
          {
              if (Command != null)
                  return Command.CanExecute(parameter);
              return false;
          }
      
          public void Execute(object parameter)
          {
              Command.Execute(parameter);
          }
      
          public event EventHandler CanExecuteChanged;
      
          private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
          {
              CommandReference commandReference = d as CommandReference;
              ICommand oldCommand = e.OldValue as ICommand;
              ICommand newCommand = e.NewValue as ICommand;
      
              if (oldCommand != null)
              {
                  oldCommand.CanExecuteChanged -= commandReference.CanExecuteChanged;
              }
              if (newCommand != null)
              {
                  newCommand.CanExecuteChanged += commandReference.CanExecuteChanged;
              }
          }
      
          #endregion
      
          #region Freezable
      
          protected override Freezable CreateInstanceCore()
          {
              throw new NotImplementedException();
          }
      
          #endregion
      }
      

      在 Xaml 中将此添加到 UserControl 资源中:

      <UserControl.Resources>
          <Base:CommandReference x:Key="SearchCommandRef" Command="{Binding Path = SomeCommand}"/>
      

      实际的 TextBox 如下所示:

       <TextBox Text="{Binding Path=SomeText}">
                          <TextBox.InputBindings>
                              <KeyBinding Command="{StaticResource SearchCommandRef}" Key="Enter"/>
                          </TextBox.InputBindings>
                      </TextBox>
      

      我不记得我从哪里得到这个代码,但这个网站也解释了它;

      http://www.netframeworkdev.com/windows-presentation-foundation-wpf/invoke-a-command-with-enter-key-after-typing-in-a-textbox-21909.shtml

      【讨论】:

        【解决方案5】:
        <TextBox Text="{Binding SerachString, UpdateSourceTrigger=PropertyChanged}">
            <TextBox.InputBindings>
                <KeyBinding Command="{Binding SearchCommand}" Key="Enter" />
            </TextBox.InputBindings>
        </TextBox>
        

        这应该可以正常工作。100%

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-11-27
          • 2013-09-16
          • 1970-01-01
          • 2017-12-23
          • 2015-06-07
          • 1970-01-01
          • 1970-01-01
          • 2020-06-03
          相关资源
          最近更新 更多