Papriker
Papriker

Reputation: 77

How to use the RelayCommand Class

I've recently gotten a trainee position in which I have to learn C# and VB. To learn both of them my supervisor told me to rebuild the Windows 10 Standard Calculator. My C# version works, but my VB Version doesn't. In my C# Version I used this RelayCommand Class:

public class RelayCommand : ICommand
{
    private readonly Action<object> execute;
    private readonly Func<object, bool>  canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        this.execute = execute;
        this.canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return this.canExecute == null || this.canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        this.execute(parameter);
    }
}

While in VB I'm using this one:

Public Class RelayCommand

    Implements ICommand

#Region "Fields"

    Private ReadOnly _execute As Action(Of Object)

    Private ReadOnly _canExecute As Predicate(Of Object)

#End Region

#Region "Constructors"

    Public Sub New(ByVal execute As Action(Of Object))

        Me.New(execute, Nothing)

    End Sub


    Public Sub New(ByVal execute As Action(Of Object), ByVal canExecute As Predicate(Of Object))

        If execute Is Nothing Then

            Throw New ArgumentNullException("execute")

        End If

        _execute = execute

        _canExecute = canExecute

    End Sub

#End Region

#Region "ICommand Members"

    <DebuggerStepThrough()> _

    Public Function CanExecute(ByVal parameter As Object) As Boolean Implements ICommand.CanExecute

        Return If(_canExecute Is Nothing, True, _canExecute(parameter))

    End Function

    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 System.Object, ByVal e As System.EventArgs)

        End RaiseEvent

    End Event

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

        _execute(parameter)

    End Sub

#End Region

End Class

I got both of them from SO. In my C# Version of the calculator I would implement a RelayCommand as the following:

public class MainViewModel : ViewModelBase
{
    public RelayCommand DisplayEnter { get; set; }

    public MainViewModel()
    {
        DisplayEnter = new RelayCommand(o => DisplayEnterCommand((Numbers)o));
    }

    private void DisplayEnterCommand()
    {
        //DoSomething
    }
}

A void in C# is a function that doesn't return a value. Since I tried to do it just like in C#, I did the following in my ViewModel in VB:

Public Class MainViewModel
    Inherits ViewModelBase

    Public Property DisplayEnter As RelayCommand
    Public Sub New()
        DisplayEnter = New RelayCommand(NumberButtonCommand("5"))
    End Sub

    Public Sub NumberButtonCommand(number As String)
        //DoSomething
    End Sub
End Class

VisualStudio tells me that my Sub doesn't return a value. I get the error-code BC30491.

Why doesn't this work just like in C#? Is the RelayCommand entirely different than the C# Version? Do I need to use a Function instead of Sub? What Value should I be returning?

I'm thankful for EVERY answer. Please keep in mind that I'm new to programming and StackOverflow.

Upvotes: 0

Views: 1702

Answers (2)

Dave Doknjas
Dave Doknjas

Reputation: 6542

I don't think the fix you used is correct. The VB version of the constructor should be:

Public Sub New()
    DisplayEnter = New RelayCommand(Sub(o) DisplayEnterCommand(CType(o, Numbers)))
End Sub

You have to be careful with coding: the first change that compiles is not necessarily the correct fix.

Upvotes: 2

Papriker
Papriker

Reputation: 77

I've found the fix.

Public Sub New()
    DisplayEnter = New RelayCommand(NumberButtonCommand("5"))
End Sub

Needs to be

Public Sub New()
        DisplayEnter = New RelayCommand(AddressOf NumberButtonCommand)
    End Sub

Upvotes: 0

Related Questions