Compartilhar via


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.

Consulte também

Conceitos

Visão geral de Comando

Referência

ICommandSource

ICommand

RoutedCommand