将C#中的ActionCommand:ICommand翻译成VB.net

14

我发现了一个名为 ActionCommand 的 C# 类,它实现了 ICommand 接口,并基于委托来实现 Execute 和 CanExecute 方法。到目前为止,看起来非常完美。

  public class ActionCommand : ICommand
  {
    private readonly Action<object> _executeHandler;
    private readonly Func<object, bool> _canExecuteHandler;

    public ActionCommand(Action<object> execute, Func<object, bool> canExecute)
    {
      if (execute == null)
        throw new ArgumentNullException("Execute cannot be null");
      _executeHandler = execute;
      _canExecuteHandler = canExecute;
    }

    public event EventHandler CanExecuteChanged
    {
      add { CommandManager.RequerySuggested += value; }
      remove { CommandManager.RequerySuggested -= value; }
    }
    public void Execute(object parameter)
    {
      _executeHandler(parameter);
    }
    public bool CanExecute(object parameter)
    {
      if (_canExecuteHandler == null)
        return true;
      return _canExecuteHandler(parameter);
    }
  }

现在我已将其翻译成我需要的VB.net变体(使用代码转换器和一些手动操作)

Public Class ActionCommand
  Implements ICommand

  Public Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged

  Private ReadOnly _executeHandler As Action(Of Object)
  Private ReadOnly _canExecuteHandler As Func(Of Object, Boolean)

  Public Sub New(ByVal execute As Action(Of Object),
                 ByVal canExecute As Func(Of Object, Boolean))
    If execute Is Nothing Then
      Throw New ArgumentNullException("Execute cannot be null")
    End If
    _executeHandler = execute
    _canExecuteHandler = canExecute
  End Sub

  Public Sub Execute(ByVal parameter As Object) Implements ICommand.Execute
    _executeHandler(parameter)
  End Sub

  Public Function CanExecute(ByVal parameter As Object) As Boolean Implements ICommand.CanExecute
    If (_canExecuteHandler Is Nothing) Then
      Return True
    End If
    Return _canExecuteHandler(parameter)
  End Function
End Class

我的问题围绕着CanExecuteChanged和从CommandManager.RequerySuggested注册/映射事件到CanExecuteChanged。在线代码转换器建议采用以下方法:

Public Custom Event CanExecuteChanged As EventHandler
    AddHandler(ByVal value As EventHandler)
        CommandManager.RequerySuggested += value
    End AddHandler
    RemoveHandler(ByVal value As EventHandler)
        CommandManager.RequerySuggested -= value
    End RemoveHandler
End Event

但这不能满足ICommand.CanExecuteChanged。请问有人可以帮忙翻译或解决这个问题吗?

3个回答

9

我认为你想要的更像是:

    Public Custom Event CanExecuteChanged As EventHandler _
                   Implements ICommand.CanExecuteChanged
        AddHandler(ByVal value As EventHandler)
            AddHandler CommandManager.RequerySuggested, value
        End AddHandler

        RemoveHandler(ByVal value As EventHandler)
            RemoveHandler CommandManager.RequerySuggested, value
        End RemoveHandler

        RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
            CanExecute(sender)
        End RaiseEvent
    End Event

我已经寻找这个东西有一段时间了...谢谢 :) - Alex

9
Public Custom Event CanExecuteChanged As EventHandler
    AddHandler(ByVal value As EventHandler)
        AddHandler CommandManager.RequerySuggested, value
    End AddHandler
    RemoveHandler(ByVal value As EventHandler)
        RemoveHandler CommandManager.RequerySuggested, value
    End RemoveHandler
End Event

5
谢谢。是的,此外,通过HadleyHope的RaiseEvent部分,自定义事件与ICommand接口相匹配。 - Markus

8
这篇来自MALIGUI .NET BLOG的文章可能会有所帮助:
Public Custom Event CanExecuteChanged As EventHandler _
    Implements ICommand.CanExecuteChanged
        AddHandler(ByVal value As EventHandler)
            Dim handler2 As EventHandler
            Dim canExecuteCommand = __CanExecuteCommand
            Do
                handler2 = canExecuteCommand
                Dim handler3 = DirectCast(System.Delegate.Combine(handler2, value), EventHandler)
                canExecuteCommand = Interlocked.CompareExchange((__CanExecuteCommand), handler3, handler2)
            Loop While (Not canExecuteCommand Is handler2)
            __CanExecuteCommand = canExecuteCommand
        End AddHandler
        RemoveHandler(ByVal value As EventHandler)
            Dim handler2 As EventHandler
            Dim canExecuteCommand = __CanExecuteCommand
            Do
                handler2 = canExecuteCommand
                Dim handler3 = DirectCast(System.Delegate.Remove(handler2, value), EventHandler)
                canExecuteCommand = Interlocked.CompareExchange((__CanExecuteCommand), handler3, handler2)
            Loop While (Not canExecuteCommand Is handler2)
            __CanExecuteCommand = canExecuteCommand
        End RemoveHandler
        RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
            If (__CanExecuteCommand IsNot Nothing) Then
                __CanExecuteCommand.Invoke(sender, e)
            End If
        End RaiseEvent
    End Event

8
关键是在RaiseEvent周围部分。通过这样做,自定义事件可以实现ICommand.CanExecuteChanged。我以这种方式简化了它,使它看起来有些类似于MarkJ的答案。 - Markus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接