Практическое руководство. Реализация ICommandSource
В этом примере показано, как создать источник команды, реализовав ICommandSource. Источник команды — это объект, который знает, как для вызова команды. ICommandSource Интерфейс предоставляет три члена: Command, CommandParameter, и CommandTarget. Command — Это команда, которая будет вызываться. CommandParameter — Это тип пользовательских данных, который передается из источника команды методу, который обрабатывает команду. CommandTarget — Это объект, для которого выполняется команда.
В этом примере класс создается который подклассы Slider управления и реализует ICommandSource.
Пример
WPF предоставляет ряд классов, которые реализуют ICommandSource, такие как Button, MenuItem, и ListBoxItem. Источник команды определяет, как он вызывает команду. Button и MenuItem вызывают команду при щелчке. Объект ListBoxItem вызывает команду при его выборе. Эти классы становится только команды источнику их Command свойству.
В этом примере команда будет вызываться при перемещении ползунка или, точнее говоря, при Value изменении свойства.
Ниже приведено определение класса.
public class CommandSlider : Slider, ICommandSource
{
public CommandSlider() : base()
{
}
Следующим шагом является реализация ICommandSource членов. В этом примере свойства реализуются как DependencyProperty объектов. Это включает свойства для использования привязки данных. Дополнительные сведения о DependencyProperty , представлена в разделе Общие сведения о свойствах зависимостей. Дополнительные сведения о привязке данных см. в разделе Общие сведения о привязке данных.
Только Command свойство показан здесь.
// 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);
}
}
Ниже приведен 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);
}
Следующим шагом является добавление и удаление команды, связанный с источника команды. Command Свойство не может просто быть перезаписан при добавлении новой команды, так как обработчики событий, связанные с предыдущей командой, если таковая имела место, сначала необходимо удалить.
// 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;
}
}
Последним шагом является создание логики для CanExecuteChanged обработчика и Execute метод.
CanExecuteChanged Событие сообщает источнику команды, может измениться, возможность команды для выполнения на текущей цели команды. При получении этого события источник команды обычно вызывает CanExecute метод о команде. Если команда не может выполнить на текущей цели команды, источник команды обычно отключается. Если команда может выполняться для текущего целевого объекта команды, источник команды обычно включает себя.
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;
}
}
}
}
Последний шаг — Execute метод. Если команда является RoutedCommand, RoutedCommand Execute метод вызван; в противном случае — значение ICommand Execute вызывается метод.
// 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);
}
}
}