2017-02-20 74 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類,如果命令屬性,預計實現System.Windows.Input.ICommand類?我在哪裏創建Invoker的實例,設置NewCommand並運行它?一般來說,我對如何用自己的模式替換模式的默認實現有點困惑。任何建議,歡迎。

+2

這似乎沒有道理。分配給Button的'Command'屬性的對象必須實現'System.Windows.Input.ICommand'。 – Clemens

+0

也許我的自定義ICommand接口應該從System.Windows.Input.ICommand繼承?或者有使用Click屬性的工作? – eXPerience

+0

「如果Command屬性需要實現System.Windows.Input.ICommand的類,那麼如何綁定我的NewCommand類?」你不能。您必須將Button的Command屬性設置爲實現內置ICommand接口的對象。 – mm8

回答

1

儘管我懷疑自定義命令接口和實現是否有意義,但您可能會創建一個自定義附加的Command屬性,該屬性在其PropertyChangedCallback中附加了一個Click處理程序。 Click處理程序然後將執行自定義命令。

以下代碼示例聲明自定義ICustomCommand接口,並在靜態CustomCommandEx類中聲明附加的Command屬性。

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的屬性。