《深入浅出WPF》读书笔记.9Command系统

背景

命令系统是wpf的核心机制之一。

Command系统

命令和路由事件的区别

命令具有约束性,路由事件不具有约束性。

命令的参数

命令关联:用于监测命令,判断命令是否可执行。通过binding可以绑定多个命令。

基础案例

<Window x:Class="CommandDemo.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:CommandDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel x:Name="sp1" VerticalAlignment="Center">
            <TextBox x:Name="tb1" Width="120" Height="40" BorderBrush="Orange" Margin="5"></TextBox>
            <Button x:Name="btn1" Width="120" Height="40" Content="命令执行" Margin="5" ></Button>
        </StackPanel>
    </Grid>
</Window>
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 CommandDemo
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            InitializeCommand();
        }
        //1.声明并定义命令
        private RoutedCommand clearCommand = new RoutedCommand("Clear", typeof(MainWindow));

        private void InitializeCommand()
        {
            //将命令赋给命令源(发送者)
            this.btn1.Command = clearCommand;
            this.clearCommand.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Alt));

            //指定命令目标
            this.btn1.CommandTarget = this.tb1;
            
            //进行命令关联
            CommandBinding binding = new CommandBinding();
            binding.Command = this.clearCommand;
            binding.CanExecute += Binding_CanExecute;
            binding.Executed += Binding_Executed;

            //把命令关联放到外围控件上
            this.sp1.CommandBindings.Add(binding); 
        }

        //命令发送到目标后 被调用
        private void Binding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.tb1.Text = "";
            e.Handled = true;
        }

        //探测命令是否可以被执行时调用
        private void Binding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (this.tb1.Text.Trim() == "")
            {
                e.CanExecute = false;
            }
            else
            {
                e.CanExecute = true;
            }
            e.Handled = true;
        }
    }
}

自定义命令

从ICommand开始写

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace CommandDemo
{
    public class ClearCommand : ICommand
    {
        //当命令执行状态改变时应当被激发
        public event EventHandler? CanExecuteChanged;

        //判断是否执行
        public bool CanExecute(object? parameter)
        {
            throw new NotImplementedException();
        }

        //用于执行
        public void Execute(object? parameter)
        {
            IView view=parameter as IView;
            if (view != null)
            {
                view.Clear();
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CommandDemo
{
    public  interface IView
    {
        bool isChanged { get; set;}

        void SetBinding();
        void Clear();
        void Save();
        void Refresh();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 CommandDemo
{
    /// <summary>
    /// MyCommandSource.xaml 的交互逻辑
    /// </summary>
    public partial class MyCommandSource : UserControl, ICommandSource
    {
        public MyCommandSource()
        {
            InitializeComponent();
        }

        public ICommand Command { get; set; }

        public object CommandParameter { get; set; }

        public IInputElement CommandTarget { get; set; }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);

            if (this.CommandTarget != null) { 
            this.Command.Execute(this.CommandTarget);
            }
        }
    }
}
<Window x:Class="CommandDemo.UserDefinedCommandDemo"
        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:CommandDemo"
        mc:Ignorable="d"
        Title="UserDefinedCommandDemo" Height="300" Width="400">
    
        <StackPanel>
        <local:MyCommandSource x:Name="myCtrl">
            <TextBlock Text="自定义命令" Background="AliceBlue" Width="120" TextAlignment="Center"></TextBlock>
        </local:MyCommandSource>
        <local:Miniview x:Name="mv1">
            
        </local:Miniview>
        </StackPanel>
   
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Shapes;

namespace CommandDemo
{
    /// <summary>
    /// UserDefinedCommandDemo.xaml 的交互逻辑
    /// </summary>
    public partial class UserDefinedCommandDemo : Window
    {
        public UserDefinedCommandDemo()
        {
            InitializeComponent();
            ClearCommand clearCommand = new ClearCommand();
            this.myCtrl.Command = clearCommand;
            this.myCtrl.CommandTarget = this.mv1;
        }
    }
}

git地址

GitHub - wanghuayu-hub2021/WpfBookDemo: 深入浅出WPF的demo

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部