《深入浅出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;
}
}
}