C# 在VB.NET中实现RelayCommand(MVVM):语法问题

C# 在VB.NET中实现RelayCommand(MVVM):语法问题,c#,wpf,vb.net,mvvm,syntax,C#,Wpf,Vb.net,Mvvm,Syntax,对于一个项目,我必须使用VB.NET。我将使用MVVM,因此我必须实现一个RelayCommand类 在C#中,该类如下所示: class ActionCommand : ICommand { private Action<object> execute; private Predicate<object> canExecute; private event EventHandler CanExecuteChangedInternal;

对于一个项目,我必须使用VB.NET。我将使用MVVM,因此我必须实现一个
RelayCommand

在C#中,该类如下所示:

class ActionCommand : ICommand
{
    private Action<object> execute;
    private Predicate<object> canExecute;
    private event EventHandler CanExecuteChangedInternal;

    public ActionCommand(Action<object> execute) : this(execute, DefaultCanExecute) { }

    public ActionCommand(Action<object> exec, Predicate<object> canExec)
    {
        if (exec == null)
            throw new ArgumentNullException("execute");
        if (canExec == null)
            throw new ArgumentNullException("canExecute");
        execute = exec;
        canExecute = canExec;
    }

    public event EventHandler CanExecuteChanged
    {
        add { CanExecuteChangedInternal += value; }
        remove { CanExecuteChangedInternal -= value; }
    }

    public bool CanExecute(object param)
    {
        return canExecute != null && canExecute(param);
    }

    public void Execute(object param)
    {
        execute(param);
    }

    public void OnCanExecuteChanged()
    {
        EventHandler handler = CanExecuteChangedInternal;
        if (handler != null)
            handler.Invoke(this, EventArgs.Empty);
    }

    public void Destroy()
    {
        canExecute = _ => false;
        this.execute = _ => { return; };
    }

    private static bool DefaultCanExecute(object param)
    {
        return true;
    }  
}
Public Class RelayCommand : Implements ICommand
Dim _execute As Action(Of Object)
Dim _canExecute As Predicate(Of Object)
Dim canExecuteChangedInternal As EventHandler

Sub New(ByVal execute)
    Me.New(execute, DefaultCanExecute)
End Sub

Sub New(ByVal execute As Action(Of Object), ByVal canExec As Predicate(Of Object))
    If execute = Nothing Then
        Throw New ArgumentException("execute")
    End If
    If canExec = Nothing Then
        Throw New ArgumentException("canExec")
    End If
    _execute = execute
    _canExecute = canExec
End Sub

Public Function CanExecute(ByRef param As Object) As Boolean
    Return _canExecute <> Nothing And _canExecute(param)
End Function


Public Sub Execute(ByVal obj As Object)
    _execute(obj)
End Sub

Public Custom Event CanExecuteChanged As EventHandler
    AddHandler(ByVal value As EventHandler)
        AddHandler canExecuteChangedInternal, AddressOf value
    End AddHandler
    RemoveHandler(value As EventHandler)
        RemoveHandler canExecuteChangedInternal, AddressOf value
    End RemoveHandler
    RaiseEvent(sender As Object, e As EventArgs)

    End RaiseEvent
End Event

Public Sub OnCanExecuteChanged(ByVal param As Object)
    Dim handler As EventHandler = canExecuteChangedInternal
    If handler <> Nothing Then
        handler.Invoke(Me, EventArgs.Empty)
    End If
End Sub

Public Sub Destroy()
    _canExecute = Function(param As Object)
                      Return False
                  End Function
    Me._execute = Sub()
                      Return
                  End Sub

End Sub

Private Shared Function DefaultCanExecute(ByVal param As Object) As Boolean
    Return True
End Function

End Class
class操作命令:ICommand
{
私人行动执行;
私有谓词执行;
私有事件处理程序CanExecuteChangeInternal;
public ActionCommand(Action execute):这个(execute,DefaultCanExecute){}
公共ActionCommand(Action exec,谓词canExec)
{
if(exec==null)
抛出新的ArgumentNullException(“执行”);
if(canExec==null)
抛出新ArgumentNullException(“canExecute”);
execute=exec;
canExecute=canExec;
}
公共事件事件处理程序CanExecuteChanged
{
添加{CanExecuteChangeInternal+=value;}
删除{CanExecuteChangeInternal-=value;}
}
公共布尔CanExecute(对象参数)
{
返回canExecute!=null&&canExecute(参数);
}
公共void执行(对象参数)
{
执行(参数);
}
CanExecuteChanged()上的公共无效
{
EventHandler handler=CanExecuteChangeInternal;
if(处理程序!=null)
Invoke(this,EventArgs.Empty);
}
公共空间销毁()
{
canExecute==>false;
this.execute==>{return;};
}
私有静态bool DefaultCanExecute(对象参数)
{
返回true;
}  
}
我在VB.NET中的版本如下所示:

class ActionCommand : ICommand
{
    private Action<object> execute;
    private Predicate<object> canExecute;
    private event EventHandler CanExecuteChangedInternal;

    public ActionCommand(Action<object> execute) : this(execute, DefaultCanExecute) { }

    public ActionCommand(Action<object> exec, Predicate<object> canExec)
    {
        if (exec == null)
            throw new ArgumentNullException("execute");
        if (canExec == null)
            throw new ArgumentNullException("canExecute");
        execute = exec;
        canExecute = canExec;
    }

    public event EventHandler CanExecuteChanged
    {
        add { CanExecuteChangedInternal += value; }
        remove { CanExecuteChangedInternal -= value; }
    }

    public bool CanExecute(object param)
    {
        return canExecute != null && canExecute(param);
    }

    public void Execute(object param)
    {
        execute(param);
    }

    public void OnCanExecuteChanged()
    {
        EventHandler handler = CanExecuteChangedInternal;
        if (handler != null)
            handler.Invoke(this, EventArgs.Empty);
    }

    public void Destroy()
    {
        canExecute = _ => false;
        this.execute = _ => { return; };
    }

    private static bool DefaultCanExecute(object param)
    {
        return true;
    }  
}
Public Class RelayCommand : Implements ICommand
Dim _execute As Action(Of Object)
Dim _canExecute As Predicate(Of Object)
Dim canExecuteChangedInternal As EventHandler

Sub New(ByVal execute)
    Me.New(execute, DefaultCanExecute)
End Sub

Sub New(ByVal execute As Action(Of Object), ByVal canExec As Predicate(Of Object))
    If execute = Nothing Then
        Throw New ArgumentException("execute")
    End If
    If canExec = Nothing Then
        Throw New ArgumentException("canExec")
    End If
    _execute = execute
    _canExecute = canExec
End Sub

Public Function CanExecute(ByRef param As Object) As Boolean
    Return _canExecute <> Nothing And _canExecute(param)
End Function


Public Sub Execute(ByVal obj As Object)
    _execute(obj)
End Sub

Public Custom Event CanExecuteChanged As EventHandler
    AddHandler(ByVal value As EventHandler)
        AddHandler canExecuteChangedInternal, AddressOf value
    End AddHandler
    RemoveHandler(value As EventHandler)
        RemoveHandler canExecuteChangedInternal, AddressOf value
    End RemoveHandler
    RaiseEvent(sender As Object, e As EventArgs)

    End RaiseEvent
End Event

Public Sub OnCanExecuteChanged(ByVal param As Object)
    Dim handler As EventHandler = canExecuteChangedInternal
    If handler <> Nothing Then
        handler.Invoke(Me, EventArgs.Empty)
    End If
End Sub

Public Sub Destroy()
    _canExecute = Function(param As Object)
                      Return False
                  End Function
    Me._execute = Sub()
                      Return
                  End Sub

End Sub

Private Shared Function DefaultCanExecute(ByVal param As Object) As Boolean
    Return True
End Function

End Class
公共类RelayCommand:实现ICommand
Dim_作为动作执行(对象的)
Dim_canExecute作为谓词(对象的)
Dim CanExecuteChangeInternal作为事件处理程序
子新建(ByVal执行)
Me.New(执行、默认CanExecute)
端接头
Sub New(ByVal作为动作(对象的)执行,ByVal canExec作为谓词(对象的))
如果execute=Nothing,则
抛出新ArgumentException(“执行”)
如果结束
如果canExec=无,则
抛出新ArgumentException(“canExec”)
如果结束
_执行
_canExecute=canExec
端接头
公共函数CanExecute(ByRef param作为对象)作为布尔值
返回_canexecutenothing和_canExecute(param)
端函数
公共子执行(ByVal obj作为对象)
_执行(obj)
端接头
公共自定义事件CanExecuteChanged为EventHandler
AddHandler(作为EventHandler的ByVal值)
AddHandler CanExecuteChangeInternal,值的地址
EndAddHandler
RemoveHandler(值为EventHandler)
RemoveHandler CanExecuteChangeInternal,值的地址
末端移除处理器
RaiseEvent(发送方作为对象,e作为事件参数)
端部提升孔
结束事件
Public Sub OnCanExecuteChanged(ByVal参数作为对象)
作为EventHandler的Dim处理程序=CanExecuteChangeInternal
如果没有,那么
调用(Me,EventArgs.Empty)
如果结束
端接头
公共子系统()
_canExecute=函数(参数作为对象)
返回错误
端函数
Me._execute=Sub()
返回
端接头
端接头
私有共享函数DefaultCanExecute(ByVal参数作为对象)作为布尔值
返回真值
端函数
末级
现在我在VB中遇到以下问题:

  • 在我的构造函数中,
    DefaultCanExecute
    不被接受为另一个构造函数的参数,但在C#中,它可以正常工作
  • 添加和删除
    EventHandlers
    无效。错误消息是:“值不是方法的名称”。但它是一个事件处理程序,不是吗?C#版本在这里也适用

您的转换有很多奇怪之处: 1.引用类型需要使用“是”和“不是”。 2.您省略了第一个构造函数的类型。 3.您在“Destroy”方法中省略了第二个lambda的参数

请尝试以下操作:

Friend Class ActionCommand
    Implements ICommand

    Private _execute As Action(Of Object)
    Private _canExecute As Predicate(Of Object)
    Private Event CanExecuteChangedInternal As EventHandler

    Public Sub New(ByVal execute As Action(Of Object))
        Me.New(execute, AddressOf DefaultCanExecute)
    End Sub

    Public Sub New(ByVal exec As Action(Of Object), ByVal canExec As Predicate(Of Object))
        If exec Is Nothing Then
            Throw New ArgumentNullException("execute")
        End If
        If canExec Is Nothing Then
            Throw New ArgumentNullException("canExecute")
        End If
        _execute = exec
        _canExecute = canExec
    End Sub

    Public Custom Event CanExecuteChanged As EventHandler
        AddHandler(ByVal value As EventHandler)
            AddHandler CanExecuteChangedInternal, value
        End AddHandler
        RemoveHandler(ByVal value As EventHandler)
            RemoveHandler CanExecuteChangedInternal, value
        End RemoveHandler
        RaiseEvent(ByVal sender As System.Object, ByVal e As System.EventArgs)
            RaiseEvent CanExecuteChangedInternal(sender, e)
        End RaiseEvent
    End Event

    Public Function CanExecute(ByVal param As Object) As Boolean
        Return _canExecute IsNot Nothing AndAlso canExecute(param)
    End Function

    Public Sub Execute(ByVal param As Object)
        execute(param)
    End Sub

    Public Sub OnCanExecuteChanged()
        'referencing the hidden "Event" field of the CanExecuteChangedInternal event:
        Dim handler As EventHandler = CanExecuteChangedInternalEvent
        If handler IsNot Nothing Then
            handler.Invoke(Me, EventArgs.Empty)
        End If
    End Sub

    Public Sub Destroy()
        _canExecute = Function(underscore) False
        Me._execute = Sub(underscore)
            Return
        End Sub
    End Sub

    Private Shared Function DefaultCanExecute(ByVal param As Object) As Boolean
        Return True
    End Function
End Class

多亏了戴夫,我才把一切都搞定了。如果有人对课程的最终版本感兴趣,请点击这里:

Public Class RelayCommand : Implements ICommand
Private _execute As Action(Of Object)
Private _canExecute As Predicate(Of Object)
Private Event canExecuteChangedInternal As EventHandler

Public Sub New(ByVal execute As Object)
    Me.New(execute, AddressOf DefaultCanExecute)
End Sub

Public Sub New(ByVal execute As Action(Of Object), ByVal canExec As Predicate(Of Object))
    If execute Is Nothing Then
        Throw New ArgumentException("execute")
    End If
    If canExec Is Nothing Then
        Throw New ArgumentException("canExec")
    End If
    _execute = execute
    _canExecute = canExec
End Sub

Public Function CanExecute(ByVal param As Object) As Boolean Implements ICommand.CanExecute
    Return _canExecute IsNot Nothing AndAlso _canExecute(param)
End Function


Public Sub Execute(ByVal obj As Object) Implements ICommand.Execute
    _execute(obj)
End Sub

Public Custom Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged
    AddHandler(ByVal value As EventHandler)
        AddHandler canExecuteChangedInternal, value
    End AddHandler
    RemoveHandler(value As EventHandler)
        RemoveHandler canExecuteChangedInternal, value
    End RemoveHandler
    RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
        RaiseEvent canExecuteChangedInternal(sender, e)
    End RaiseEvent
End Event

Public Sub OnCanExecuteChanged(ByVal param As Object)
    Dim handler As EventHandler = canExecuteChangedInternalEvent
    If handler IsNot Nothing Then
        handler.Invoke(Me, EventArgs.Empty)
    End If
End Sub

Public Sub Destroy()
    _canExecute = Function(unused) False
    Me._execute = Sub(unused)
                      Return
                  End Sub
End Sub

Private Shared Function DefaultCanExecute(ByVal param As Object) As Boolean
    Return True
End Function

End Class