Como: Implement ICommandSource
Este exemplo mostra como criar uma fonte de comandos, implementando ICommandSource. Uma fonte de comandos é um objeto que sabe como invocar um comando. The ICommandSource interface expõe três membros: Command, CommandParameter, e CommandTarget. Command é o comando que será chamado. O CommandParameter é um tipo de dados definido pelo usuário que é passado da fonte de comandos para o método que trata o comando. O CommandTarget é o objeto no qual o comando está sendo executado.
Nesse exemplo, uma classe é criada que herda do controle Slider e implementa ICommandSource. Para o código fonte completo do exemplo, veja o Implementar ICommandSource exemplo.
Exemplo
O WPF fornece várias classes que implementam ICommandSource, como Button, MenuItem e ListBoxItem. Uma fonte de comando define como ele invocará um comando. Button e MenuItem chamar um comando quando eles são clicados. Um ListBoxItem chama um comando quando ele recebe um clique duplo. Essas classes só tornam-se uma fonte de comandos quando sua propriedade Command é definida.
Para esse exemplo nós iremos invocar o comando quando o controle deslizante for movido, ou mais precisamente, quando a propriedade Value for alterada.
A seguir temos a definição da classe.
public class CommandSlider : Slider, ICommandSource
{
public CommandSlider() : base()
{
}
A próxima etapa é implementar os membros de ICommandSource. Nesse exemplo, as propriedades são implementadas como objetos DependencyProperty. Isso permite que as propriedades usem associação de dados. Para obter mais informações sobre a classe DependencyProperty, consulte Visão geral sobre propriedades de dependência. Para obter mais informações, consulte Revisão de Associação de Dados.
Somente a propriedade Command é mostrada aqui.
// Make Command a dependency property so it can use databinding.
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register(
"Command",
typeof(ICommand),
typeof(CommandSlider),
new PropertyMetadata((ICommand)null,
new PropertyChangedCallback(CommandChanged)));
public ICommand Command
{
get
{
return (ICommand)GetValue(CommandProperty);
}
set
{
SetValue(CommandProperty, value);
}
}
A seguir temos a callback de alterações na DependencyProperty.
// Command dependency property change callback.
private static void CommandChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
CommandSlider cs = (CommandSlider)d;
cs.HookUpCommand((ICommand)e.OldValue,(ICommand)e.NewValue);
}
A próxima etapa é adicionar e remover o comando que está associado com a fonte de comandos. A propriedade Command não pode ser simplesmente sobrescrita quando um comando novo é adicionado, pois os manipuladores de eventos associados ao comando anterior, se houver algum, devem ser removidos primeiro.
// Add a new command to the Command Property.
private void HookUpCommand(ICommand oldCommand, ICommand newCommand)
{
// If oldCommand is not null, then we need to remove the handlers.
if (oldCommand != null)
{
RemoveCommand(oldCommand, newCommand);
}
AddCommand(oldCommand, newCommand);
}
// Remove an old command from the Command Property.
private void RemoveCommand(ICommand oldCommand, ICommand newCommand)
{
EventHandler handler = CanExecuteChanged;
oldCommand.CanExecuteChanged -= handler;
}
// Add the command.
private void AddCommand(ICommand oldCommand, ICommand newCommand)
{
EventHandler handler = new EventHandler(CanExecuteChanged);
canExecuteChangedHandler = handler;
if (newCommand != null)
{
newCommand.CanExecuteChanged += canExecuteChangedHandler;
}
}
A última etapa é criar a lógica para o manipulador CanExecuteChanged e o método Execute.
O evento CanExecuteChanged informa a fonte de comandos que a capacidade do comando de ser executado no atual alvo do comando pode ter sido alterada. Quando uma fonte de comandos recebe esse evento, ela normalmente chama o método CanExecute do comando. Se o comando não pode executar sobre o alvo atual do comando, a fonte de comandos geralmente desativará a si própria. Se o comando pode executar sobre o alvo atual do comando, a fonte de comandos geralmente ativará a si própria.
private void CanExecuteChanged(object sender, EventArgs e)
{
if (this.Command != null)
{
RoutedCommand command = this.Command as RoutedCommand;
// If a RoutedCommand.
if (command != null)
{
if (command.CanExecute(CommandParameter, CommandTarget))
{
this.IsEnabled = true;
}
else
{
this.IsEnabled = false;
}
}
// If a not RoutedCommand.
else
{
if (Command.CanExecute(CommandParameter))
{
this.IsEnabled = true;
}
else
{
this.IsEnabled = false;
}
}
}
}
A última etapa é o método Execute. Se o comando for um RoutedCommand, o método Execute de RoutedCommand é chamado; caso contrário, o método Execute de ICommand é chamado.
// If Command is defined, moving the slider will invoke the command;
// Otherwise, the slider will behave normally.
protected override void OnValueChanged(double oldValue, double newValue)
{
base.OnValueChanged(oldValue, newValue);
if (this.Command != null)
{
RoutedCommand command = Command as RoutedCommand;
if (command != null)
{
command.Execute(CommandParameter, CommandTarget);
}
else
{
((ICommand)Command).Execute(CommandParameter);
}
}
}
O Implementar ICommandSource exemplo cria um aplicativo de exemplo que usa esta fonte de comandos.