Обновленный заголовок: почему ICommand.CanExecute вызывается все время, а не как событие?

Я принимаю шаблон MVVM в WPF и научился использоватьCommand, Но в моей реализации делегат, которого я назначил для реализацииCanExecute всегда называется. Я имею в виду, если я поставлю точку останова внутри функции делегата, это показывает, что эта функция продолжает вызываться. Насколько я понимаю (и естественный способ мышления, но, конечно, я могу ошибаться), этого делегата вызывают только тогда, когда я каким-то образом уведомляю об изменении состояния, и тогдаCommandManager (пере) проверяетCanExecute собственности и изменитьIsEnabled свойство элемента пользовательского интерфейса.

Вот моя реализация VB.NET, которую я получил с версии C #. Я заметил, что мне нужно было внести некоторые изменения в перенесенный код для его компиляции. Может ли это быть в основе C # и VB.NET отличается? Так может кто-нибудь предоставить мне оригинальную реализацию VB.NET, или указать мне, что не так, или сделать, если я правильно понимаю поведение Command?

Вот моя версия VB.NET:

 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

И то, как я создаю экземпляр объекта, выглядит примерно так:

MyCommand = New CommandBase(AddressOf CommandExec, AddressOf CanExecuteExec)

где CanExecuteExec, конечно, имеет такую подпись:

Private Function CanExecuteExec(obj As Object) As Boolean

Как я уже говорил,CanExecuteExec все время звонят. Я думаю, это неэффективно, представьте, что у меня есть сотниCommand объекты и большая частьCanExecute из них не меняются большую часть времени.

ОБНОВИТЬ:

Кто-то говоритCanExecute на самом деле все время звонят, в то время как другие говорят обратное. Я не эксперт в этом, но я должен сказать, что второе мнение звучит более естественно и имеет больше смысла для меня. Хотя мне все еще нужно выяснить, так ли это, почему WPF все время обнаруживает изменения, чтобы постоянно проверятьCanExecute

Ответы на вопрос(3)

Ваш ответ на вопрос