WPF Command 命令
参考
- 命令概述
- gpt
环境
软件/系统 | 版本 | 说明 |
---|---|---|
Windows | Windows 10 专业版 22H2 19045.4046 | |
Microsoft Visual Studio | Microsoft Visual Studio Community 2022 (64 位) - 17.6.5 | |
Microsoft .Net SDK | 8.0.101 | 手动安装 |
Microsoft .Net SDK | 7.0.306 | Microsoft Visual Studio 携带 |
.net | 6.x | 创建当前文章演示 WPF 项目时指定 .net 版本所选择的框架 |
正文
概念
WPF 中的路由命令模型可分解为四个主要概念:命令、命令源、命令目标和命令绑定:
- 命令是要执行的操作。
- 命令源是调用命令的对象,命令源通常实现 ICommandSource 接口。。
- 命令目标是在其上执行命令的对象,命令目标是 Executed 和 CanExecute 的路由开始的元素。仅当 ICommand 为 RoutedCommand 时,ICommandSource 上的 CommandTarget 属性才适用 如果在 ICommandSource 上设置 CommandTarget 并且相应的命令不是 RoutedCommand,则忽略命令目标。命令源可以显式设置命令目标。
- 命令绑定是将命令逻辑映射到命令的对象。
WPF 中的命令是通过实现 ICommand 接口创建的。 ICommand 公开了两种方法 Execute 和 CanExecute,以及一个事件 CanExecuteChanged。 Execute 执行与该命令关联的操作。 CanExecute 确定是否可以在当前命令目标上执行该命令。 如果集中管理命令操作的命令管理器检测到命令源中存在一个可能使已引发命令无效但尚未由命令绑定执行的更改,则会引发 CanExecuteChanged。 ICommand 的 WPF 实现是 RoutedCommand 类。
许多这些命令都包含一组默认输入绑定。 例如,如果指定应用程序处理复制命令,则可自动获取键盘绑定“CTRL+C”。此外,还可获得其他输入设备的绑定,例如 Tablet PC 笔势和语音信息。
系统预置命令
名称 | 功能 |
---|---|
ApplicationCommands | 提供一组与应用程序相关的标准命令。 |
NavigationCommands | 提供一组标准的与导航相关的命令。 |
MediaCommands | 提供媒体相关命令的标准集。 |
EditingCommands | 提供一组标准的编辑相关命令。 |
ComponentCommands | 提供一组与组件相关的标准命令,这些命令具有预定义的按键输入笔势和 Text 属性。 |
-
以下示例显示了如何设置 MenuItem,以便在单击时它将调用 TextBox 上的 Paste 命令,假定 TextBox 具有键盘焦点。
Paste 命令是命令,MenuItem 是命令源,TextBox 是命令目标,命令绑定由 TextBox 控件提供。 值得注意的是,CommandBinding 并不总是由作为命令目标类的控件提供。 通常,CommandBinding 必须由应用程序开发者创建,否则 CommandBinding 可能会附加到命令目标的上级元素。
- 图片
- xaml
<StackPanel> <Menu> <MenuItem Command="ApplicationCommands.Paste" /> </Menu> <TextBox /> </StackPanel>
- 图片
-
显式设置命令目标。
-
图片
-
xaml
<StackPanel> <Menu> <MenuItem Command="ApplicationCommands.Paste" CommandTarget="{Binding ElementName=mainTextBox1}" /> </Menu> <TextBox Name="mainTextBox" /> <TextBox Name="mainTextBox1" /> <TextBox Name="mainTextBox2" /> </StackPanel>
-
自定义命令
-
RoutedCommand
- xaml
<Window x:Class="学习.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:学习" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="MainWindow" Width="850" Height="700" mc:Ignorable="d"> <Window.Resources /> <Window.CommandBindings> <CommandBinding CanExecute="GetButtonContentCmdCanExecute" Command="{x:Static local:MainWindow.GetButtonContentCmd}" Executed="GetButtonContentCmdExecuted" /> </Window.CommandBindings> <Grid> <StackPanel> <!-- RoutedCommand https://github.com/Microsoft/WPF-Samples/tree/main/Input%20and%20Commands/CustomRoutedCommand --> <Button Command="{x:Static local:MainWindow.GetButtonContentCmd}" Content="按钮1" /> <Button Command="{x:Static local:MainWindow.GetButtonContentCmd}" Content="按钮2" /> <Button Command="{x:Static local:MainWindow.GetButtonContentCmd}" Content="按钮3" /> </StackPanel> </Grid> </Window>
- c#
using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace 学习 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public static RoutedCommand GetButtonContentCmd = new RoutedCommand(); // 执行命令方法 private void GetButtonContentCmdExecuted(object sender, ExecutedRoutedEventArgs e) { // object sender 的值居然是 Window 对象 Button? b = e.Source as Button; if (b != null) { MessageBox.Show(b.Content.ToString()); } } //判断是否可执行命令 private void GetButtonContentCmdCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; } public MainWindow() { InitializeComponent(); } } }
- xaml
-
ICommand MVVM 模式
- MainWindow.xaml
<Window x:Class="学习.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:学习" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:sys="clr-namespace:System;assembly=mscorlib" Title="MainWindow" Width="850" Height="700" mc:Ignorable="d"> <Window.DataContext> <local:MainWindowViewModel /> </Window.DataContext> <Grid> <StackPanel> <TextBlock Width="120" Height="60" Text="{Binding Name}" /> <Button Width="120" Height="60" Command="{Binding OnShowNameCmd}" Content="点击" /> </StackPanel> </Grid> </Window>
- MainWindow.xaml.cs
using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace 学习 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } }
- MainWindowViewModel.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; namespace 学习 { // 继承 INotifyPropertyChanged 并在属性 set 时触发 PropertyChanged 则会通知前端同步修改为最新值 internal class MainWindowViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; // string name = "xiaqiuchu"; public string Name { get { return name; } set { name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name))); } } private void ShowName(object? parameter) { MessageBox.Show(name); } // 当前的软件版本,需要定义 get 才能够正确触发 public ICommand OnShowNameCmd { get; } public MainWindowViewModel() { OnShowNameCmd = new OnShowNameCommand(ShowName); } } public class OnShowNameCommand : ICommand { private Action<object?> _execute; public OnShowNameCommand(Action<object?> execute) { _execute = execute; } public event EventHandler? CanExecuteChanged; // 是否可以/符合执行事件 public bool CanExecute(object? parameter) { Trace.WriteLine("CanExecute"); return true; } // 事件执行方法 public void Execute(object? parameter) { Trace.WriteLine("Execute"); _execute(parameter); } } }
- MainWindow.xaml
博 主 :夏秋初
地 址 :https://www.cnblogs.com/xiaqiuchu/p/18046164
如果对你有帮助,可以点一下 推荐 或者 关注 吗?会让我的分享变得更有动力~
转载时请带上原文链接,谢谢。
地 址 :https://www.cnblogs.com/xiaqiuchu/p/18046164
如果对你有帮助,可以点一下 推荐 或者 关注 吗?会让我的分享变得更有动力~
转载时请带上原文链接,谢谢。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
2022-03-01 Java 线程工具类 加法/减法/信号量
2022-03-01 Java 将线程不安全的集合转换为线程安全的集合