Bagikan melalui


Cara: Menerapkan ICommandSource

Contoh ini menunjukkan cara membuat sumber perintah dengan menerapkan ICommandSource. Sumber perintah adalah objek yang tahu cara memanggil perintah. Antarmuka ICommandSource mengekspos tiga anggota:

  • Command: perintah yang akan dipanggil.
  • CommandParameter: jenis data yang ditentukan pengguna yang diteruskan dari sumber perintah ke metode yang menangani perintah.
  • CommandTarget: objek tempat perintah dijalankan.

Dalam contoh ini, kelas dibuat yang mewarisi dari Slider kontrol dan mengimplementasikan ICommandSource antarmuka.

Contoh

WPF menyediakan sejumlah kelas yang mengimplementasikan ICommandSource, seperti Button, , MenuItemdan Hyperlink. Sumber perintah menentukan bagaimana perintah memanggil perintah. Kelas-kelas ini memanggil perintah saat diklik dan hanya menjadi sumber perintah saat propertinya Command diatur.

Dalam contoh ini, Anda akan memanggil perintah saat slider dipindahkan, atau lebih akurat, saat Value properti diubah.

Berikut ini adalah definisi kelas:

public class CommandSlider : Slider, ICommandSource
{
    public CommandSlider() : base()
    {
    }
Public Class CommandSlider
    Inherits Slider
    Implements ICommandSource
    Public Sub New()
        MyBase.New()

    End Sub

Langkah selanjutnya adalah mengimplementasikan anggota ICommandSource . Dalam contoh ini, properti diimplementasikan sebagai DependencyProperty objek. Ini memungkinkan properti untuk menggunakan pengikatan data. Untuk informasi selengkapnya tentang DependencyProperty kelas, lihat Gambaran Umum Properti Dependensi. Untuk informasi selengkapnya tentang pengikatan data, lihat Gambaran Umum Pengikatan Data.

Hanya properti yang Command ditampilkan di sini.

// 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

Berikut ini adalah DependencyProperty panggilan balik perubahan:

// 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

Langkah selanjutnya adalah menambahkan dan menghapus perintah yang terkait dengan sumber perintah. Properti Command tidak dapat ditimpa begitu saja ketika perintah baru ditambahkan, karena penanganan aktivitas yang terkait dengan perintah sebelumnya, jika ada, harus dihapus terlebih dahulu.

// 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

Langkah selanjutnya adalah membuat logika untuk CanExecuteChanged handler.

Peristiwa memberi CanExecuteChanged tahu sumber perintah bahwa kemampuan perintah untuk dijalankan pada target perintah saat ini mungkin telah berubah. Ketika sumber perintah menerima peristiwa ini, biasanya memanggil CanExecute metode pada perintah . Jika perintah tidak dapat dijalankan pada target perintah saat ini, sumber perintah biasanya akan menonaktifkan dirinya sendiri. Jika perintah dapat dijalankan pada target perintah saat ini, sumber perintah biasanya akan mengaktifkan dirinya sendiri.

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

Langkah terakhir adalah Execute metode . Jika perintah adalah RoutedCommand,ExecuteRoutedCommandmetode dipanggil; jika tidak, ICommandExecute metode dipanggil.

// 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

Baca juga