Gör så här: Implementera ICommandSource
Det här exemplet visar hur du skapar en kommandokälla genom att implementera ICommandSource. En kommandokälla är ett objekt som vet hur man anropar ett kommando. Gränssnittet ICommandSource exponerar tre medlemmar:
- Command: kommandot som ska anropas.
- CommandParameter: en användardefinierad datatyp som skickas från kommandokällan till den metod som hanterar kommandot.
- CommandTarget: objektet som kommandot körs på.
I det här exemplet skapas en klass som ärver från Slider kontroll och implementerar ICommandSource-gränssnittet.
Exempel
WPF innehåller ett antal klasser som implementerar ICommandSource, till exempel Button, MenuItemoch Hyperlink. En kommandokälla definierar hur ett kommando anropas. Dessa klasser anropar ett kommando när de klickas och de blir bara en kommandokälla när deras Command egenskap har angetts.
I det här exemplet anropar du kommandot när skjutreglaget flyttas, eller närmare bestämt, när egenskapen Value ändras.
Följande är klassdefinitionen:
public class CommandSlider : Slider, ICommandSource
{
public CommandSlider() : base()
{
}
Public Class CommandSlider
Inherits Slider
Implements ICommandSource
Public Sub New()
MyBase.New()
End Sub
Nästa steg är att implementera ICommandSource medlemmar. I det här exemplet implementeras egenskaperna som DependencyProperty objekt. Detta gör att egenskaperna kan använda databindning. Mer information om klassen DependencyProperty finns i översikten över beroendeegenskaper. För mer information om databindning, se databindningsöversikten .
Endast egenskapen Command visas här.
// 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
Följande är DependencyProperty ändra återanrop:
// 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
Nästa steg är att lägga till och ta bort kommandot som är associerat med kommandokällan. Egenskapen Command kan inte bara skrivas över när ett nytt kommando läggs till, eftersom händelsehanterarna som är associerade med föregående kommando, om det fanns ett, måste tas bort först.
// 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
Nästa steg är att skapa logik för CanExecuteChanged-hanteraren.
Händelsen CanExecuteChanged meddelar kommandokällan att kommandots möjlighet att köras på det aktuella kommandomålet kan ha ändrats. När en kommandokälla tar emot den här händelsen anropas vanligtvis metoden CanExecute i kommandot. Om kommandot inte kan köras på det aktuella kommandomålet inaktiverar kommandokällan vanligtvis sig själv. Om kommandot kan köras på det aktuella kommandomålet aktiverar kommandokällan vanligtvis sig själv.
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
Det sista steget är metoden Execute. Om kommandot är en RoutedCommandanropas metoden RoutedCommandExecute. annars anropas metoden ICommandExecute.
// 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
Se även
- ICommandSource
- ICommand
- RoutedCommand
- översikt över -kommandon
.NET Desktop feedback