wpf - input binding examples

Input binding is the mechanism that you can invoke a command by some input measures, such as mouse input or keyboard input. 

 

 

The concrete classes to InputBindings are MouseBinding and KeyBinding. 

 

 

Since Input bindings are something that you may use often, below shows you an example on how to use the Input Bindings. (normally you will create input binding on parent element so that you can fire the command from a bigger container )

 

 

Suppose that you can create a class that implements the ICommand, and this class has some input gestures which indicate what input it expects to fire the commands. 

 

 

 

namespace InputBindingsTest
{
  public class SimpleDelegateCommand  : ICommand
  {

    public Key GestureKey { get; set; }
    public ModifierKeys GestureModifier { get; set; }
    public MouseAction MouseGesture { get; set; }

    Action<object> _executeDelegate;

    public SimpleDelegateCommand(Action<object> executeDelegate)
    {
      _executeDelegate = executeDelegate;
    }

    public bool CanExecute(object parameter)
    {
      return true;
      // if the CanExecute changes, raise the OnCanExecutedChanged()
      //OnCanExecutedChanged(null);
    }

    public event EventHandler CanExecuteChanged;

    protected virtual void OnCanExecutedChanged(EventArgs eventargs)
    {
      var changed = CanExecuteChanged;
      if (changed != null)
      {
        changed(this, eventargs);
      }
    }

    public void Execute(object parameter)
    {
      _executeDelegate(parameter);
    }
  }
}
 

 

and with this class, we are going to create a concrete command , which represents a action to change the background of container. 

 

The name of the Command is ChangeColorCommand, and we want to indicate that user can fire the command through the use of "Ctrl + C" or "Right Mouse ClicK"; Also, in this source file, the handler to the ChangeColorCommand is also defined.

 

 

namespace InputBindingsTest
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
      InitializeCommand();
    }


    public SimpleDelegateCommand ChangeColorCommand
    {
      get { return changeColorCommand; }
    }

    private SimpleDelegateCommand changeColorCommand;


    private void InitializeCommand()
    {
      originalColor = this.Background;
      changeColorCommand = new SimpleDelegateCommand(x => this.ChangeColor(x));
      DataContext = this;
      changeColorCommand.GestureKey = Key.C;
      changeColorCommand.GestureModifier = ModifierKeys.Control;
      changeColorCommand.MouseGesture = MouseAction.RightClick;
    }

    private Brush originalColor, alternateColor;

    private void ChangeColor(object colorString)
    {
      if (colorString == null)
      {
        return;
      }

      Color newColor = (Color)ColorConverter.ConvertFromString((string)colorString);
      alternateColor = new SolidColorBrush(newColor);

      if (this.Background == originalColor)
      {
        this.Background = alternateColor;
      }
      else
      {
        this.Background = originalColor;
      }
    }

  }
}
 

 

 

Now, to make the Input binding really effective, below is the xaml file. where we set up the Input binding on the container element (in this case, the MainWindow), and we uses the concrete binding such as KeyBinding and the MouseBinding;

 

 

<Window x:Class="InputBindingsTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.InputBindings>
        <KeyBinding Command="{Binding ChangeColorCommand}"
                CommandParameter="{Binding ElementName=colorPicker, Path=SelectedItem}"
                Key="{Binding ChangeColorCommand.GestureKey}"
                Modifiers="{Binding ChangeColorCommand.GestureModifier}"/>
        <MouseBinding Command="{Binding ChangeColorCommand}"
                  CommandParameter="{Binding ElementName=colorPicker, Path=SelectedItem}"
                  MouseAction="{Binding ChangeColorCommand.MouseGesture}"/>
    </Window.InputBindings>
    <StackPanel Background="Transparent">
        <Button Content="Change Color"
                Command="{Binding ChangeColorCommand}"
                CommandParameter="{Binding ElementName=colorPicker, Path=SelectedItem}" />
        <ListBox Name="colorPicker"
           Background="Transparent"
           xmlns:sys="clr-namespace:System;assembly=mscorlib">
            <sys:String>Red</sys:String>
            <sys:String>Green</sys:String>
            <sys:String>Blue</sys:String>
            <sys:String>Yellow</sys:String>
            <sys:String>Orange</sys:String>
            <sys:String>Purple</sys:String>
        </ListBox>
    </StackPanel>
</Window>
 

 

now you can change the color of the background either through the use of "Right Mouse" click or you can simpley press "Ctrl + C";

 

### 关于 WPF 中 QueryCommand 的用法 在 Windows Presentation Foundation (WPF) 开发中,`QueryCommand` 并不是一个官方的标准命令名称或功能[^1]。然而,在某些场景下,开发者可能会自定义 `ICommand` 实现来支持查询型操作逻辑。这种情况下,“QueryCommand”可能被用来表示一种用于查询数据或者状态的命令。 #### 自定义 QueryCommand 的实现方式 如果需要创建一个名为 `QueryCommand` 的命令,可以基于 `ICommand` 接口进行扩展。以下是具体实现: ```csharp using System; using System.Windows.Input; public class QueryCommand : ICommand { private readonly Func<bool> _canExecute; private readonly Action<object> _executeAction; public QueryCommand(Action<object> executeAction, Func<bool> canExecute = null) { _executeAction = executeAction ?? throw new ArgumentNullException(nameof(executeAction)); _canExecute = canExecute; } public bool CanExecute(object parameter) { return _canExecute?.Invoke() ?? true; // 如果未提供CanExecute,则默认返回true } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public void Execute(object parameter) { _executeAction(parameter); } } ``` 上述代码展示了如何通过继承 `ICommand` 来创建一个通用的查询命令类。此命令允许传递参数并执行指定的操作,同时还可以设置条件判断逻辑 `_canExecute` 以决定当前状态下是否能够触发该命令。 #### 使用示例 下面是一个简单的例子,展示如何将 `QueryCommand` 绑定到按钮上,并根据某种条件动态调整其可用性。 ```xml <Window x:Class="WpfApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid> <Button Content="Run Query" Command="{Binding QueryCommand}" IsEnabled="{Binding CanRunQuery}"/> </Grid> </Window> ``` 对应的 ViewModel 如下所示: ```csharp using System.ComponentModel; public class MainViewModel : INotifyPropertyChanged { private bool _canRunQuery = true; public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public QueryCommand QueryCommand { get; set; } public bool CanRunQuery { get => _canRunQuery; set { if (_canRunQuery != value) { _canRunQuery = value; OnPropertyChanged(nameof(CanRunQuery)); } } } public MainViewModel() { QueryCommand = new QueryCommand(param => { Console.WriteLine($"Executing query with param: {param}"); }, () => CanRunQuery); // Simulate a condition change after some time System.Timers.Timer timer = new System.Timers.Timer(5000); timer.Elapsed += (s, e) => CanRunQuery = false; timer.Start(); } } ``` 在这个例子中,当计时器到期后会禁用按钮的功能,从而阻止进一步调用 `QueryCommand`。 --- ### 高性能图表库中的应用案例 除了基本的命令模式外,一些第三方库也利用类似的机制实现了更复杂的交互行为。例如,在 SciChart.Wpf.Examples 库中,许多高级图表控件都依赖于 MVVM 架构下的命令绑定技术来完成用户输入与后台计算之间的同步[^3]。 --- ### 图像编辑工具中的潜在用途 对于构建图像编辑工具而言,`QueryCommand` 可能会被设计成负责加载文件、保存进度或是发起异步任务等功能的一部分[^4]。由于这类程序通常涉及大量资源管理以及多线程处理需求,因此合理运用命令模式可以帮助简化复杂流程的设计。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值