Como implementar ICommandSource
Este exemplo mostra como criar uma fonte de comando implementando ICommandSourceo . Uma fonte de comando é um objeto que sabe como invocar um comando. A ICommandSource interface expõe três membros:
- Command: o comando que será invocado.
- CommandParameter: um tipo de dados definido pelo usuário que é passado da origem do comando para o método que manipula o comando.
- CommandTarget: o objeto no qual o comando está sendo executado.
Neste exemplo, é criada uma classe que herda do Slider controle e implementa a ICommandSource interface.
Exemplo
O WPF fornece várias classes que implementam ICommandSource, como Button, MenuItem, e Hyperlink. Uma fonte de comandos define como se invoca um comando. Essas classes invocam um comando quando são clicadas e só se tornam uma fonte de comando quando sua Command propriedade é definida.
Neste exemplo, você invocará o comando quando o controle deslizante for movido ou, mais precisamente, quando a Value propriedade for alterada.
Veja a seguir a definição de classe:
public class CommandSlider : Slider, ICommandSource
{
public CommandSlider() : base()
{
}
Public Class CommandSlider
Inherits Slider
Implements ICommandSource
Public Sub New()
MyBase.New()
End Sub
O próximo passo é implementar os ICommandSource membros. Neste exemplo, as propriedades são implementadas como DependencyProperty objetos. Isso permite que as propriedades usem associação de dados. Para obter mais informações sobre a DependencyProperty classe, consulte a Visão geral das propriedades de dependência. Para obter mais informações sobre associação de dados, consulte Visão geral de associação de dados.
Apenas a propriedade é mostrada Command 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);
}
}
' Make Command a dependency property so it can use databinding.
Public Shared ReadOnly CommandProperty As DependencyProperty =
DependencyProperty.Register("Command", GetType(ICommand),
GetType(CommandSlider),
New PropertyMetadata(CType(Nothing, ICommand),
New PropertyChangedCallback(AddressOf CommandChanged)))
Public ReadOnly Property Command1() As ICommand Implements ICommandSource.Command
Get
Return CType(GetValue(CommandProperty), ICommand)
End Get
End Property
Public Property Command() As ICommand
Get
Return CType(GetValue(CommandProperty), ICommand)
End Get
Set(ByVal value As ICommand)
SetValue(CommandProperty, value)
End Set
End Property
Veja a seguir o retorno de chamada de DependencyProperty alteração:
// 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);
}
' Command dependency property change callback.
Private Shared Sub CommandChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Dim cs As CommandSlider = CType(d, CommandSlider)
cs.HookUpCommand(CType(e.OldValue, ICommand), CType(e.NewValue, ICommand))
End Sub
A próxima etapa é adicionar e remover o comando que está associado à fonte de comando. A Command propriedade não pode ser simplesmente substituída quando um novo comando é adicionado, pois os manipuladores de eventos associados ao comando anterior, se houver, 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;
}
}
' Add a new command to the Command Property.
Private Sub HookUpCommand(ByVal oldCommand As ICommand, ByVal newCommand As ICommand)
' If oldCommand is not null, then we need to remove the handlers.
If oldCommand IsNot Nothing Then
RemoveCommand(oldCommand, newCommand)
End If
AddCommand(oldCommand, newCommand)
End Sub
' Remove an old command from the Command Property.
Private Sub RemoveCommand(ByVal oldCommand As ICommand, ByVal newCommand As ICommand)
Dim handler As EventHandler = AddressOf CanExecuteChanged
RemoveHandler oldCommand.CanExecuteChanged, handler
End Sub
' Add the command.
Private Sub AddCommand(ByVal oldCommand As ICommand, ByVal newCommand As ICommand)
Dim handler As New EventHandler(AddressOf CanExecuteChanged)
canExecuteChangedHandler = handler
If newCommand IsNot Nothing Then
AddHandler newCommand.CanExecuteChanged, canExecuteChangedHandler
End If
End Sub
A próxima etapa é criar lógica para o CanExecuteChanged manipulador.
O CanExecuteChanged evento notifica a origem do comando de que a capacidade do comando de ser executado no destino do comando atual pode ter sido alterada. Quando uma fonte de comando recebe esse evento, ela normalmente chama o CanExecute método no comando. Se o comando não puder executar no destino do comando atual, geralmente, a fonte de comando se desabilitará automaticamente. Se o comando puder executar no destino do comando atual, geralmente, a fonte de comando se habilitará por conta 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;
}
}
}
}
Private Sub CanExecuteChanged(ByVal sender As Object, ByVal e As EventArgs)
If Me.Command IsNot Nothing Then
Dim command As RoutedCommand = TryCast(Me.Command, RoutedCommand)
' If a RoutedCommand.
If command IsNot Nothing Then
If command.CanExecute(CommandParameter, CommandTarget) Then
Me.IsEnabled = True
Else
Me.IsEnabled = False
End If
' If a not RoutedCommand.
Else
If Me.Command.CanExecute(CommandParameter) Then
Me.IsEnabled = True
Else
Me.IsEnabled = False
End If
End If
End If
End Sub
A última etapa é o Execute método. Se o comando for um RoutedCommand, o RoutedCommandExecute método é chamado; caso contrário, o ICommandExecute método é 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);
}
}
}
' If Command is defined, moving the slider will invoke the command;
' Otherwise, the slider will behave normally.
Protected Overrides Sub OnValueChanged(ByVal oldValue As Double, ByVal newValue As Double)
MyBase.OnValueChanged(oldValue, newValue)
If Me.Command IsNot Nothing Then
Dim command As RoutedCommand = TryCast(Me.Command, RoutedCommand)
If command IsNot Nothing Then
command.Execute(CommandParameter, CommandTarget)
Else
CType(Me.Command, ICommand).Execute(CommandParameter)
End If
End If
End Sub
Confira também
.NET Desktop feedback