wpf之命令

前言

wpf中命令Command主要用于将 UI 控件(如按钮、菜单项)的触发动作与执行该动作的逻辑代码解耦,主要在MVVM模式使用。

1、命令的三个核心概念

1.1 命令源

命令源是触发命令的 UI 元素,它实现了 ICommandSource 接口,例如 Button、MenuItem、KeyGesture(快捷键),我们最常用的就是鼠标左键点击Button来触发命令,这里的Button就是命令源,一般通过设置命令源的 Command 属性来关联一个命令,比如下面的代码中设置Command属性的值为"ApplicationCommands.Paste",就是关联了一个复制命令。

csharp 复制代码
 <Button Content="粘贴" 
                Command="ApplicationCommands.Paste"
                CommandTarget="{Binding ElementName=TargetTextBox}"
              Width="40" />

1.2 命令目标

命令目标是命令执行操作的对象。通常是拥有焦点的控件。可以通过命令源的 CommandTarget 属性显式设置,如果未设置,则默认为拥有键盘焦点的元素,比如下面的代码 CommandTarget="{Binding ElementName=TargetTextBox}"就是指定了命令操作的对象是TargetTextBox这个TextBox控件。

csharp 复制代码
 <Button Content="粘贴" 
                Command="ApplicationCommands.Paste"
                CommandTarget="{Binding ElementName=TargetTextBox}"
              Width="40" />
            <TextBox x:Name="TargetTextBox"   Width=" 40" Height=" 20"/>

1.3 命令绑定

命令绑定指定了两件事,一个是当命令被执行时,运行什么代码(对应 Execute方法);另一个是

命令何时可以执行(对应 CanExecute方法),这两个方法都是在接口ICommand中定义,对于部分命令比如"ApplicationCommands.Copy"、"ApplicationCommands.Paste"不需要我们自己写命令绑定,但是一般自定义的命令需要我们自己重写 CanExecute和 Execute方法。

csharp 复制代码
public interface ICommand
    {
        event EventHandler CanExecuteChanged;
        bool CanExecute(object parameter);
      
        void Execute(object parameter);
    }

2、系统自带命令

任何实现了 ICommand 接口的类都可以作为 WPF 命令

2.1 复制和粘贴

下面的代码中我们先用鼠标选中"123"中的"23",然后点击"复制"按钮,最后点击"粘贴"按钮,这样你就能看到文本"23"被粘贴到最下方的TextBox 中,点击"复制"按钮时就是执行了"ApplicationCommands.Copy"命令,点击"粘贴"按钮就是执行"ApplicationCommands.Paste"命令。

csharp 复制代码
<Window x:Class="wpf之命令.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:wpf之命令"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">


    <Grid>
        <StackPanel >
            <Button  Content="复制"  Width=" 40" Height=" 20" Command="ApplicationCommands.Copy" CommandTarget="{Binding ElementName= tbx_test }" />
            <TextBox x:Name="tbx_test" Width=" 40" Height=" 20"/>
            <Button Content="粘贴" 
                Command="ApplicationCommands.Paste"
                CommandTarget="{Binding ElementName=TargetTextBox}"
              Width="40" />
            <TextBox x:Name="TargetTextBox"   Width=" 40" Height=" 20"/>
        </StackPanel >
    </Grid>
</Window>

3、自定义命令

3.1 MVVM模式-无参数命令

当点击按钮"MVVM模式"时,会触发cmd_test命令绑定的Test方法执行,这样会在控制台打印"自定义命令,参数:"

csharp 复制代码
<Window x:Class="wpf之命令.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:wpf之命令"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">


    <Grid>
        <StackPanel >
            <Button  Width="80" Height=" 20" Content="MVVM模式" Command="{Binding cmd_test}" />
        </StackPanel >
    </Grid>
</Window>
csharp 复制代码
public class DelegateCommand : ICommand
    {
        private readonly Action<object> _execute;
        private readonly Func<object, bool> _canExecute;

        public DelegateCommand(Action<object> execute, Func<object, bool> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute != null)
            {
                return _canExecute(parameter);
            }
            else
            {
                return true;
            }
        }

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


        public event EventHandler CanExecuteChanged
        {
            add => CommandManager.RequerySuggested += value;
            remove => CommandManager.RequerySuggested -= value;
        }

      
    }
csharp 复制代码
public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string propname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propname));
            }
        }
    }
csharp 复制代码
 public class ViewModel : ViewModelBase
    {

        public DelegateCommand cmd_test { get; set; }

        public ViewModel()
        {
            cmd_test = new DelegateCommand(Test);
        }


        private void Test(object param)
        {
            Console.WriteLine($"自定义命令,参数:{param}");
        }
    }

3.2 MVVM模式-有参数命令

当点击按钮"MVVM模式-有参"时,会触发cmd_test命令绑定的Test方法执行,这样会在控制台打印"自定义命令,参数:123"

csharp 复制代码
<Window x:Class="wpf之命令.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:wpf之命令"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">


    <Grid>
        <StackPanel Height="419" VerticalAlignment="Bottom" >
            <Button  Width="120" Height=" 20" Content="MVVM模式-有参" Command="{Binding cmd_test}" CommandParameter="123" />
        </StackPanel >
    </Grid>
</Window>

马工撰写的年入30万+C#上位机项目实战必备教程(点击下方链接即可访问文章目录)

1、《C#串口通信从入门到精通》

2、《C#与PLC通信从入门到精通 》

3、《C# Modbus通信从入门到精通》

4、《C#Socket通信从入门到精通 》

5、《C# MES通信从入门到精通》

6、《winform控件从入门到精通》

7、《C#操作MySql数据库从入门到精通》

相关推荐
小猪快跑爱摄影3 小时前
【AutoCad 2025】【C#】零基础教程(四)——MText 常见属性
c#·autocad
炼钢厂4 小时前
C#6——DateTime
c#
Lv11770085 小时前
Visual Studio中的多态
ide·笔记·c#·visual studio
wuguan_5 小时前
C#:多态函数重载、态符号重载、抽象、虚方法
开发语言·c#
我不是程序猿儿6 小时前
【C#】ScottPlot的Refresh()
开发语言·c#
工程师0076 小时前
C# 基于 HSL 与基恩士 PLC 通信
c#·mc协议·基恩士plc
张人玉9 小时前
c# DataSet 类
数据库·c#·dataset
秦苒&10 小时前
【C语言】详解数据类型和变量(一):数据类型介绍、 signed和unsigned、数据类型的取值范围、变量、强制类型转换
c语言·开发语言·c++·c#
c#上位机10 小时前
C#异步编程之async、await
开发语言·c#
郑州光合科技余经理10 小时前
实战分享:如何构建东南亚高并发跑腿配送系统
java·开发语言·javascript·spring cloud·uni-app·c#·php