当控件(例如:Button)完成ICommand的执行时,有没有办法获得回调?

时间:2011-10-13 08:55:06

标签: wpf callback commandbinding

我有一个用户控件,它接受ICommand Dependency属性,允许VM指定命令。

有没有办法可以在我的控件按钮(最终执行ICommand)中附加一个处理程序(回调),以便我的控件知道命令执行何时完成?

感谢您的关注。

1 个答案:

答案 0 :(得分:0)

您可以创建抽象的CallbackableCommand来引发回调方法。

abstract class CallbackableCommand : ICommand
  {
    private IInputElement getRaisedElement()
    {
      return Keyboard.FocusedElement;      
    }

    public void Execute(object parameter)
    {
      ExecuteImpl(parameter);
      var element = getRaisedElement();
      if(element == null) return;

      //var ci = typeof(ExecutedRoutedEventArgs).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0];
      //var routedEventArgs = (RoutedEventArgs)ci.Invoke(new object[] { this, parameter });
      var routedEventArgs = new RoutedEventArgs();
      //routedEventArgs.RoutedEvent = CommandManager.ExecutedEvent;
      routedEventArgs.RoutedEvent = Callbackable.CommandExecutedEvent;
      routedEventArgs.Source = element;
      routedEventArgs.Handled = false;

      element.RaiseEvent(routedEventArgs);            
    }    

    public abstract void ExecuteImpl(object parameter);

    abstract public bool CanExecute(object parameter);

    abstract public event EventHandler CanExecuteChanged;
  }

从CallbackableCommand继承您的命令并覆盖CanExecute,CanExecuteChanged和ExecuteImpl(而不是Execute)

  class SimpleCommand : CallbackableCommand
  {
    public override void ExecuteImpl(object parameter)
    {
      MessageBox.Show("Simple command execute with parameter: " 
        + parameter ?? "null");
    }

    public override bool CanExecute(object parameter)
    {
      return true;
    }

    public override event EventHandler CanExecuteChanged;
  }

指定CommandExecuted事件的自有元素:

  public class Callbackable : ContentControl
  {
    public static readonly RoutedEvent CommandExecutedEvent = EventManager.RegisterRoutedEvent(
        "CommandExecuted", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Callbackable));

    // Provide CLR accessors for the event
    public event RoutedEventHandler CommandExecuted
    {
      add { AddHandler(CommandExecutedEvent, value); }
      remove { RemoveHandler(CommandExecutedEvent, value); }
    }
  }

修改 在您的控件中指定Callbackable.CommandExecuted事件

<Grid>
    <Grid.Resources>
        <local:SimpleCommand x:Key="btnCommand" />            
    </Grid.Resources>
    <local:Callbackable>
        <Button Command="{StaticResource btnCommand}"   
                CommandParameter="param"                
                local:Callbackable.CommandExecuted="Button_Executed" >
            Click me
        </Button>
    </local:Callbackable>
</Grid>

执行事件处理程序:

private void Button_Executed(object sender, ExecutedRoutedEventArgs e)
{
  MessageBox.Show("Executed");
}