命令具有一处声明,处处使用的特点。微软在WPF类库中准备了一些便捷的命令库,包括:
(1)、ApplicationCommands;
(2)、ComponentCommands;
(3)、NavigationCommands;
(4)、MediaCommands;
(5)、EditingCommands
都是静态类,而命令就是用这些类的静态只读属性以单件模式暴露出来。
命令源一定是实现了ICommandSource接口的对象,而ICommandSource有一个属性是CommandParameter.示例如下:
XAML代码:
<Window x:Class="MyTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF" Height="240" Width="360">
<Grid Margin="6">
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition Height="4"/>
<RowDefinition Height="24"/>
<RowDefinition Height="4"/>
<RowDefinition Height="24"/>
<RowDefinition Height="4"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Name:" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="0"/>
<TextBox x:Name="nameTextBox" Margin="60, 0, 0, 0" Grid.Row="0"/>
<Button Content="New Teacher" Command="New" CommandParameter="Teacher" Grid.Row="2"/>
<Button Content="New Student" Command="New" CommandParameter="Student" Grid.Row="4"/>
<ListBox x:Name="listBoxNewItems" Grid.Row="6"/>
</Grid>
<Window.CommandBindings>
<CommandBinding Command="New" CanExecute="New_CanExecute" Executed="New_Executed"/>
</Window.CommandBindings>
</Window>
C#代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void New_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (string.IsNullOrEmpty(this.nameTextBox.Text))
e.CanExecute = false;
else
e.CanExecute = true;
}
private void New_Executed(object sender, ExecutedRoutedEventArgs e)
{
string name = this.nameTextBox.Text;
if (e.Parameter.ToString() == "Teacher")
this.listBoxNewItems.Items.Add(string.Format("New Teacher: {0},学而不厌,诲人不倦。", name));
if (e.Parameter.ToString() == "Student")
this.listBoxNewItems.Items.Add(string.Format("New Student: {0},好好学习,天天向上。", name));
}
}
============================================================================
自定义命令示例如下:
XAML代码:
<UserControl x:Class="MyTest.MiniView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="114" d:DesignWidth="200">
<Border CornerRadius="5" BorderBrush="LawnGreen" BorderThickness="2">
<StackPanel>
<TextBox x:Name="textBox1" Margin="5"/>
<TextBox x:Name="textBox2" Margin="5, 0"/>
<TextBox x:Name="textBox3" Margin="5"/>
<TextBox x:Name="textBox4" Margin="5, 0"/>
</StackPanel>
</Border>
</UserControl>
C#代码:
public partial class MiniView : UserControl, IView
{
public MiniView()
{
InitializeComponent();
}
public bool IsChanged { get; set; }
public void SetBinding() { }
public void Refresh() { }
public void Save() { }
public void Clear()
{
this.textBox1.Clear();
this.textBox2.Clear();
this.textBox3.Clear();
this.textBox4.Clear();
}
}
--------------------------------------------------------------------------------------------------------------------------------------
public interface IView
{
bool IsChanged { get; set; }
void SetBinding();
void Refresh();
void Clear();
void Save();
}
public class MyCommandSource : UserControl, ICommandSource
{
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 (null != this.CommandTarget)
this.Command.Execute(this.CommandTarget);
}
}
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 (null != view)
view.Clear();
}
}
-------------------------------------------------------------------------------------------------------------------------------
主窗体XAML代码:
<Window x:Class="MyTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyTest"
Title="WPF" Height="205" Width="250">
<StackPanel>
<local:MyCommandSource x:Name="ctrlClear" Margin="10">
<TextBlock Text="清除" FontSize="16" TextAlignment="Center" Background="LightGreen" Width="80"/>
</local:MyCommandSource>
<local:MiniView x:Name="miniView"/>
</StackPanel>
</Window>
C#代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ClearCommand clearCmd = new ClearCommand();
this.ctrlClear.Command = clearCmd;
this.ctrlClear.CommandTarget = this.miniView;
}
}
==============================================================================
正规的方法是把命令声明在静态全局的地方供所有对象使用。