gpt4 book ai didi

wpf - 更新标题 : Why ICommand. CanExecute 一直被调用,而不是像事件一样工作?

转载 作者:行者123 更新时间:2023-12-04 13:27:30 26 4
gpt4 key购买 nike

我在 WPF 中采用了 MVVM 模式,并且已经学会了 Command 的使用。 .但在我的实现中,我分配的委托(delegate)来实现 CanExecute总是被调用。我的意思是,如果我在委托(delegate)函数中放置一个断点,则表明该函数不断被调用。根据我的理解(也是一种自然的思维方式,但我当然可能是错的),只有当我以某种方式通知状态更改时才会调用该委托(delegate),而那是 CommandManager (重新)检查 CanExecute属性并修改IsEnabled UI 元素的属性。

这是我最初从 C# 版本获得的 VB.NET 实现。我确实注意到我需要对移植的代码进行一些更改才能编译它。会不会是 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

最佳答案

在您的 CanExecuteDelegate你有钩到CommandManager.RequerySuggested .

所以,每当CommandManager.RequerySuggested提高你的CanExecuteDelegate将被调用。

CommandManager.RequerySuggested event is raised whenever changes to the command source are detected by the command manager which ranges from Keyboard.KeyUpEvent, Mouse.ClickEvent etc.



此外,CommandManager 有一个静态方法 - InvalidateRequerySuggested这会强制 CommandManager 引发 RequerySuggestedEvent。因此,您也可以调用它来手动验证您的命令。

如果您想掌握提高 CanExecute 的控制权,可以使用 Delegate Command棱镜提供。 CanExecute只有当您明确调用 RaiseCanExecuteChanged() 时,才会调用委托(delegate)。委托(delegate)命令公开的方法。

结合评论回答

Breakpoint is hitting every time on turning to VS since CommandManager RequerySuggested event gets called on lost focus of window and on activation property changed of window. That's why you notice that breakpoint is hitting every now and then when you move to VS since focus moves from WPF window to Visual Studio.

关于wpf - 更新标题 : Why ICommand. CanExecute 一直被调用,而不是像事件一样工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18962189/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com