在 VB.NET 中实现 RelayCommand (MVVM):语法问题
Implementing RelayCommand (MVVM) in VB.NET: Syntax problems
对于一个项目,我必须使用 VB.NET。我要使用MVVM,所以我必须实现一个RelayCommand
class。
在 C# 中,class 如下所示:
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;
}
}
我在 VB.NET 中的版本如下所示:
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
现在我在VB中遇到了以下问题:
- 在我的构造函数中
DefaultCanExecute
不被接受为另一个构造函数的参数,但在 C# 中它工作正常。
- 添加和删除
EventHandlers
不起作用。错误信息是:"value is not a name of a method"。但它是一个事件处理程序,不是吗? C# 版本也适用于此。
您的转换有很多奇怪之处:
1. 引用类型需要使用'Is'和'IsNot'。
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
多亏了 Dave,我才得以解决所有问题。如果有人对 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
对于一个项目,我必须使用 VB.NET。我要使用MVVM,所以我必须实现一个RelayCommand
class。
在 C# 中,class 如下所示:
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;
}
}
我在 VB.NET 中的版本如下所示:
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
现在我在VB中遇到了以下问题:
- 在我的构造函数中
DefaultCanExecute
不被接受为另一个构造函数的参数,但在 C# 中它工作正常。 - 添加和删除
EventHandlers
不起作用。错误信息是:"value is not a name of a method"。但它是一个事件处理程序,不是吗? C# 版本也适用于此。
您的转换有很多奇怪之处: 1. 引用类型需要使用'Is'和'IsNot'。 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
多亏了 Dave,我才得以解决所有问题。如果有人对 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