Aktualisierter Titel: Warum wird ICommand.CanExecute die ganze Zeit aufgerufen, anstatt wie ein Ereignis zu arbeiten?

Ich übernehme MVVM-Muster in WPF und habe die Verwendung von gelerntCommand. Aber in meiner Implementierung der Delegat, den ich mit der Implementierung beauftragt habeCanExecute heißt immer. Ich meine, wenn ich einen Haltepunkt in die Delegate-Funktion setze, zeigt dies, dass diese Funktion immer wieder aufgerufen wird. Nach meinem Verständnis (und einer natürlichen Denkweise, aber natürlich kann ich mich irren) wird dieser Delegierte nur dann gerufen, wenn ich die Änderung des Zustands irgendwie mitteilte und dannCommandManager (erneut) prüft dieCanExecute Eigentum und ändern Sie dieIsEnabled Eigenschaft des UI-Elements.

Hier ist meine Implementierung von VB.NET, die ich ursprünglich aus einer C # -Version erhalten habe. Mir ist aufgefallen, dass ich einige Änderungen am portierten Code vornehmen musste, damit er kompiliert werden konnte. Könnte es sein, dass die Basis von C # und VB.NET anders ist? Kann mir jemand eine originale VB.NET-Implementierung zur Verfügung stellen oder mich darauf hinweisen, was falsch ist oder was tun, wenn ich das Befehlsverhalten richtig verstehe?

Hier ist meine VB.NET-Version:

 Public Class CommandBase
    Implements ICommand

    Public Property ExecuteDelegate() As Action(Of Object)

    Public Property CanExecuteDelegate() As Predicate(Of Object)

    Public Sub New()
    End Sub

    Public Sub New(execute As Action(Of Object))
        Me.New(execute, Nothing)
    End Sub

    Public Sub New(execute As Action(Of Object), canExecute As Predicate(Of Object))
        If execute Is Nothing Then
            Throw New ArgumentNullException("execute")
        End If
        ExecuteDelegate = execute
        CanExecuteDelegate = canExecute
    End Sub

    Public Function CanExecute(parameter As Object) As Boolean Implements ICommand.CanExecute
        Return If(CanExecuteDelegate Is Nothing, True, CanExecuteDelegate(parameter))
    End Function

    Public Custom Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged
        AddHandler(ByVal value As EventHandler)

            If CanExecuteDelegate IsNot Nothing Then
                AddHandler CommandManager.RequerySuggested, value
            End If

        End AddHandler
        RemoveHandler(ByVal value As EventHandler)
            If CanExecuteDelegate IsNot Nothing Then
                RemoveHandler CommandManager.RequerySuggested, value
            End If
        End RemoveHandler

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

    Public Sub Execute(parameter As Object) Implements ICommand.Execute
        If ExecuteDelegate IsNot Nothing Then ExecuteDelegate.Invoke(parameter)
    End Sub

    Public Sub RaiseCanExecuteChanged()
        CommandManager.InvalidateRequerySuggested()
    End Sub

End Class

Und wie ich ein Objekt instanziiere, ist ungefähr so:

MyCommand = New CommandBase(AddressOf CommandExec, AddressOf CanExecuteExec)

Wobei die CanExecuteExec natürlich die Signatur wie folgt hat:

Private Function CanExecuteExec(obj As Object) As Boolean

Wie ich schon sagte, dieCanExecuteExec wird die ganze Zeit angerufen. Ich denke, es ist ineffizient. Stellen Sie sich vor, ich habe Hunderte vonCommand Objekte und die meistenCanExecute von ihnen werden die meiste Zeit nicht verändert.

AKTUALISIEREN:

Jemand sagt dasCanExecute in der Tat wird die ganze Zeit angerufen, während andere das Gegenteil sagen. Ich bin kein Experte in diesem Bereich, aber ich muss sagen, dass die zweite Meinung natürlicher klingt und für mich sinnvoller ist. Obwohl ich immer noch herausfinden muss, ob das zutrifft, erkennt WPF die Änderung die ganze Zeit, damit es das überprüftCanExecute

Antworten auf die Frage(3)

Ihre Antwort auf die Frage