当前位置: 首页 > news >正文

WPF学习笔记(24)命令与ICommand

命令与ICommand

  • 一、命令
    • 1. ICommandSource
    • 2. 示例
    • 3. CommandBinding
  • 二、ICommand
    • 1.ICommand接口
    • 2. ICommand用法
    • 3. CanExecute
  • 总结


一、命令

在这里插入图片描述
官方文档:https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/advanced/commanding-overview

1. ICommandSource

在这里插入图片描述
官方文档:https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/advanced/how-to-implement-icommandsource

在这里插入图片描述

2. 示例

在这里插入图片描述
在这里插入图片描述

    <Grid><TextBox x:Name="textBox" Text="TextBox" VerticalAlignment="Top"  Height="150" Margin="219,35,187,0"/><Button x:Name="buttonCut"Content="剪切"Command="ApplicationCommands.Cut"CommandTarget="{Binding ElementName=textBox}"Height="100" Margin="219,233,419,102"/><Button x:Name="buttonPaste"Content="粘贴"Command="ApplicationCommands.Paste"CommandTarget="{Binding ElementName=textBox}" Margin="453,233,187,107"/></Grid>

在这里插入图片描述

3. CommandBinding

在这里插入图片描述
在这里插入图片描述

  • 当TEXTBOX内容长度大于0时,CanExecute被判断为true
  • true可以启用命令源按钮,false禁用按钮
    在这里插入图片描述
<Window.CommandBindings><CommandBinding Command="ApplicationCommands.Cut" CanExecute="my_CanExecute" Executed="my_Execute"/>
</Window.CommandBindings><Grid><TextBox x:Name="textBox" Text="TextBox" VerticalAlignment="Top"  Height="150" Margin="219,35,187,0"/><Button x:Name="buttonCut" Margin="219,233,419,102" Height="100" Content="剪切"Command="ApplicationCommands.Cut"/><Button x:Name="buttonPaste"Content="粘贴"Command="ApplicationCommands.Paste"CommandTarget="{Binding ElementName=textBox}"Margin="453,233,187,107"/>
</Grid>
public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();}private void my_Execute(object sender, ExecutedRoutedEventArgs e){Console.WriteLine("Execute!!!");textBox.Cut();}private void my_CanExecute(object sender, CanExecuteRoutedEventArgs e){e.CanExecute = textBox.SelectionLength > 0;}
}

二、ICommand

在这里插入图片描述

官方文档:https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.input.icommand?view=net-9.0

1.ICommand接口

在这里插入图片描述

ICommand接口的属性与事件如下:
在这里插入图片描述

2. ICommand用法

在这里插入图片描述

    <Grid><TextBox HorizontalAlignment="Left" Margin="222,62,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="422" Height="102"/><Button x:Name="button1" Content="  自定义命令" HorizontalAlignment="Left" Margin="222,217,0,0" VerticalAlignment="Top" Height="64" Width="145"/><Button x:Name="button2" Content="触发事件" HorizontalAlignment="Left" Margin="499,217,0,0" VerticalAlignment="Top" Height="64" Width="145"/></Grid>

在MainWindow.xaml.cs文件内自定义命令接口
在这里插入图片描述
在这里插入图片描述

<Window.Resources><local:MyCommand x:Key="MyCMD" />
</Window.Resources>
<Grid><TextBox x:Name="textBox" HorizontalAlignment="Left" Margin="222,62,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="422" Height="102"/><Button x:Name="button1" Content="  自定义命令"Command="{StaticResource MyCMD}"CommandParameter="{Binding ElementName=textBox,Path=Text}"HorizontalAlignment="Left" Margin="222,217,0,0" VerticalAlignment="Top" Height="64" Width="145"/><Button x:Name="button2" Content="触发事件" HorizontalAlignment="Left" Margin="499,217,0,0" VerticalAlignment="Top" Height="64" Width="145"/>
</Grid>
public class MyCommand : ICommand
{public event EventHandler CanExecuteChanged;public bool CanExecute(object parameter){return true;//按钮可以点击//return false;//按钮不可点击}//Execute方法中实现命令处理逻辑public void Execute(object parameter){MessageBox.Show(parameter.ToString());}
}

以下为CanExecuteChanged的事件解释:
在这里插入图片描述

public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();}private void button2_Click(object sender, RoutedEventArgs e){MyCommand c = Resources["MyCMD"] as MyCommand;//触发CanExecuteChangedc.RaiseCanExecuteChanged();}
}
//实现ICommand接口
public class MyCommand : ICommand
{public event EventHandler CanExecuteChanged;public bool CanExecute(object parameter){String str = parameter as String;return str?.Length > 0;//return true;//按钮可以点击//return false;//按钮不可点击}//Execute方法中实现命令处理逻辑public void Execute(object parameter){MessageBox.Show(parameter.ToString());}//定义一个方法,手动触发CanExecuteChanged事件public void RaiseCanExecuteChanged() {//表面上,没有为 CanExecuteChanged 这个事件添加任何订阅方法//例如CanExecuteChanged += fun;//但是我们为按钮设置命令时,自动加入了一个此事件订阅的方法,//并且这个订阅的方法,会去调用命令的CanExecute//可通过Delegate查看CanExecuteChanged的来源与内容Delegate[] delegates = CanExecuteChanged.GetInvocationList();//delegates内查看到 System.Windows.Input.CanExecuteChangedEventManager+HandlerSink"//OnCanExecuteChangedCanExecuteChanged?.Invoke(this, EventArgs.Empty);}

加粗样式

3. CanExecute

以ButtonBase为例介绍,调用了OnCommandChanged
在这里插入图片描述
OnCommandChanged调用了HookCommand
在这里插入图片描述

HookCommand调用了AddHandler,CanExecute调用了CanExecuteCommandSource在这里插入图片描述
在这里插入图片描述
AddHandler调用的PrivateAddHandler又new 了一个HandlerSink
在这里插入图片描述

HandlerSink将OnCommandChanged函数添加到Icommand接口的CanExecuteChanged
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

总结

关于ButtonBase、CanExecuteChangedEventManager、commandHelpers的详细原理、我们可以参考WPF框架的源码
https://github.com/dotnet/wpf/blob/main/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Primitives/ButtonBase.cs
https://github.com/dotnet/wpf/blob/main/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/CanExecuteRoutedEventArgs.cs
https://github.com/dotnet/wpf/blob/main/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Commands/CommandHelpers.cs

http://www.xdnf.cn/news/1082233.html

相关文章:

  • 【Oracle专栏】分区表增加分区
  • 【机器学习深度学习】模型参数量、微调效率和硬件资源的平衡点
  • Linux:多线程---深入互斥浅谈同步
  • vue中添加原生右键菜单
  • LucidShape 2024.09 最新
  • FreeCAD傻瓜教程-拉簧拉力弹簧的画法及草图的附着位置设定和Part工作台中形体构建器的妙用
  • Flutter 使用http库获取网络数据的方法(一)
  • 初识Linux:Linux开发工具gcc/g++和gdb以及Makefile的使用
  • App爬虫工具篇-appium配置
  • 【STM32实践篇】:GPIO 详解
  • 2025使用VM虚拟机安装配置Macos苹果系统下Flutter开发环境保姆级教程--上篇
  • 九、K8s污点和容忍
  • web前端面试-- MVC、MVP、MVVM 架构模式对比
  • 递归与循环
  • 高频交易服务器篇
  • A/B测试实战:页面微小改动如何带来30%转化率提升?
  • ABC413 : E Reverse 2^i
  • Vue前端项目接收webSocket信息
  • Linux网络配置与故障排除完全指南
  • 介绍electron
  • 【ES6】Latex总结笔记生成器(网页版)
  • TailWind CSS Intellisense 插件在VSCode 上不生效
  • LESS/SCSS 高效主题换肤方案
  • 基于 LangChain 实现通义千问 + Tavily 搜索 Agent 的简单实践
  • 在VMware虚拟机中安装Windows 98时,Explorer提示“该程序执行了非法操作,即将关闭”的解决办法
  • 虚拟机与容器技术详解:VM、LXC、LXD与Docker
  • php协程
  • MySQL 数据库传统方式部署主从架构的实现很详细
  • React Native 亲切的组件们(函数式组件/class组件)和陌生的样式
  • 若 VSCode 添加到文件夹内右键菜单中显示(通过reg文件方式)