Как использовать класс RelayCommand - PullRequest
0 голосов
/ 26 марта 2020

Я недавно получил стажировку, в которой я должен изучать C# и VB. Чтобы узнать их оба, мой руководитель сказал мне перестроить стандартный калькулятор Windows 10. Моя C# версия работает, но моя версия VB - нет. В моей C# версии я использовал этот класс RelayCommand:

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);
    }
}

В то время как в VB я использую этот:

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

Я получил их обоих от SO. В моей C# версии калькулятора я бы реализовал RelayCommand следующим образом:

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

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

    private void DisplayEnterCommand()
    {
        //DoSomething
    }
}

Пустота в C# - это функция, которая не возвращает значение. Поскольку я пытался сделать это так же, как в C#, я сделал следующее в моей ViewModel в 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 сообщает мне, что мой Sub не возвращает значение. Я получаю код ошибки BC30491.

Почему это не работает так же, как в C#? RelayCommand полностью отличается от версии C#? Нужно ли использовать функцию вместо Sub? Какое значение я должен возвращать?

Я благодарен за КАЖДЫЙ ответ. Помните, что я новичок в программировании и StackOverflow.

Ответы [ 2 ]

2 голосов
/ 26 марта 2020

Я не думаю, что исправление, которое вы использовали, является правильным. Версия конструктора VB должна быть:

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

Вы должны быть осторожны с кодированием: первое компилируемое изменение не обязательно является правильным исправлением.

0 голосов
/ 26 марта 2020

Я нашел исправление.

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

Должен быть

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