2017-02-20 7 views
0

Предположим, что мне не разрешено использовать классы wpf по умолчанию, интерфейс RoutedCommand, CommandBinding и ICommand. Вместо этого я должен предоставить свою собственную реализацию. Так Уточняю простой интерфейс ICommand:Выполнение шаблона команды в WPF

public interface ICommand 
{ 
    void Execute(); 
} 

сделать класс для конкретной команды:

public class NewCommand : ICommand 
{ 
    private readonly IReceiver _receiver; 
    // receiver is any class that provides implementation of a New() method 

    public NewCommand(IReceiver receiver) 
    { 
     _receiver = receiver; 
    } 
    public void Execute() 
    { 
     _receiver.New(); 
    } 
} 

Там должно быть Чешуи, а также:

public class Invoker 
{ 
    private ICommand _command; 
    public void SetCommand(ICommand c) 
    { 
     _command = c; 
    } 
    public void Run() 
    { 
     _command.Execute(); 
    } 
} 

Как подключить все это на XAML, учитывая, что при реализации по умолчанию мой код выглядит так:

public class DesignerCanvas : Canvas 
{ 
    private readonly IDesignerCommandsReceiver _receiver; 

    public DesignerCanvas() 
    { 
     _receiver = new DesignerCommandsReceiver(this); 
     CommandBindings.Add(new CommandBinding(ApplicationCommands.New, New_Executed)); 
    } 

    private void New_Executed(object sender, ExecutedRoutedEventArgs e) 
    { 
     _receiver.New(); 
    } 
} 

И кнопка, которая вызывает новую команду переплетен как:

<Button Margin="3" Width="55" Style="{StaticResource ToolBarButtonBaseStyle}" 
        Command="{x:Static ApplicationCommands.New}" 
        CommandTarget="{Binding ElementName=MyDesigner}"> 
       <Button.Content> 
        <Grid> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="4*"/> 
          <RowDefinition Height="1*"/> 
         </Grid.RowDefinitions> 
         <Image Source="Images/GenericDocument.png" Width="45"/> 
         <TextBlock Grid.Row="1" Text="New" VerticalAlignment="Bottom" HorizontalAlignment="Center"/> 
        </Grid> 
       </Button.Content> 
      </Button> 

Как связать мой класс NewCommand если атрибут Command ожидает класс, который реализует System.Windows.Input.ICommand? Где я могу создать экземпляр Invoker, установите NewCommand и запустите его? Вообще говоря, я немного смущен тем, как заменить стандартную реализацию шаблона моим собственным. Любые советы приветствуются.

+2

Это не имеет смысла. Объект, которому назначено свойство 'Command' Button, должен реализовать' System.Windows.Input.ICommand'. – Clemens

+0

Возможно, мой пользовательский интерфейс ICommand должен наследовать от System.Windows.Input.ICommand? Или есть работа с использованием атрибута Click? – eXPerience

+0

«Как связать мой класс NewCommand, если атрибут Command ожидает класс, который реализует System.Windows.Input.ICommand?" Вы не можете. Вы должны установить свойство Command Button для объекта, который реализует встроенный интерфейс ICommand. – mm8

ответ

1

Хотя я сомневаюсь, что имеет смысл иметь пользовательский интерфейс командной строки и реализацию, возможно, вы можете создать настраиваемое свойство Command, которое прикрепляет обработчик Click в свой PropertyChangedCallback. Обработчик Click затем выполнит пользовательскую команду.

Следующий образец кода объявляет пользовательский интерфейс ICustomCommand и объявляет присоединенное свойство Command в статическом классе CustomCommandEx.

public interface ICustomCommand 
{ 
    void Execute(); 
} 

public static class CustomCommandEx 
{ 
    public static readonly DependencyProperty CommandProperty = 
     DependencyProperty.RegisterAttached(
      "Command", 
      typeof(ICustomCommand), 
      typeof(CustomCommandEx), 
      new PropertyMetadata(CommandPropertyChanged)); 

    public static ICustomCommand GetCommand(DependencyObject obj) 
    { 
     return (ICustomCommand)obj.GetValue(CommandProperty); 
    } 

    public static void SetCommand(DependencyObject obj, ICustomCommand value) 
    { 
     obj.SetValue(CommandProperty, value); 
    } 

    private static void CommandPropertyChanged(
     DependencyObject obj, DependencyPropertyChangedEventArgs eventArgs) 
    { 
     var button = obj as ButtonBase; 
     var command = eventArgs.NewValue as ICustomCommand; 

     if (button != null) 
     { 
      button.Click += (s, e) => command.Execute(); 
     } 
    } 
} 

Вы бы присвоить вложенное свойство как это:

<Button local:CustomCommandEx.Command="{Binding SomeCommand}"/> 

где SomeCommand свойство в вашей модели представления, реализующий ICustomCommand.