gpt4 book ai didi

wpf - ICommand CanExecuteChanged 未更新

转载 作者:行者123 更新时间:2023-12-01 08:02:11 27 4
gpt4 key购买 nike

我正在尝试 MVVM 模式基本级别,并在 ICommand CanExecute 更改时感到震惊。我有如下 XAML 绑定(bind):

    <ListBox ItemsSource="{Binding Contact.Addresses}"  x:Name="AddressCollections" Height="152" SelectedValue="{Binding SelectedAddress}"
DockPanel.Dock="Top" />
<Button Content="Add" Command="{Binding AddAddressCommand}" DockPanel.Dock="Top" />
<Button Content="Remove" Command="{Binding DeleteAddressCommand}" DockPanel.Dock="Bottom" />

命令:
Public Class DeleteCommand
Implements ICommand

Private method As Object
Private methodname As String

Public Sub New(ByVal Controlname As String, ByVal mee As Object)
methodname = Controlname
method = mee
End Sub

Public Function CanExecute(parameter As Object) As Boolean Implements ICommand.CanExecute
Select Case methodname
Case "Address"
Return TryCast(method, ModelView.Contacts.ContactMV).CanDeleteAddress()
Case "Numbers"
Return TryCast(method, ModelView.Contacts.ContactMV).CanDeleteNumbers
Case Else : Return False
End Select
End Function

Public Event CanExecuteChanged(sender As Object, e As EventArgs) Implements ICommand.CanExecuteChanged

Public Sub Execute(parameter As Object) Implements ICommand.Execute
Select Case methodname
Case "Address"
TryCast(method, ModelView.Contacts.ContactMV).DeleteAddress()
Case "Numbers"
TryCast(method, ModelView.Contacts.ContactMV).DeleteNumbers()
Case Else

End Select
End Sub
End Class

我的模型 View :
Public Class ContactMV

Property Contact As Model.Contacts.ContactMod
Property AddAddressCommand As New Commands.AddCommand("Address", Me)
Property DeleteAddressCommand As New Commands.DeleteCommand("Address", Me)
Property SelectedAddress As Model.Contacts.AddressModel
Public Sub AddAddress()
If Contact.Addresses.Count = 0 Then
Contact.Addresses.Add(New Model.Contacts.AddressModel(Contact.Primary.ID, True))
Else
Contact.Addresses.Add(New Model.Contacts.AddressModel(Contact.Primary.ID, False))
End If

End Sub
Public Sub DeleteAddress()
If IsNothing(SelectedAddress) = False Then
Try
Contact.Addresses.Remove(SelectedAddress)
Catch ex As Exception
MsgBox("Address not found")
End Try
End If
End Sub
Public Function CanDeleteAddress()
If IsNothing(SelectedAddress) Then
Return False
Else
Return Contact.Addresses.Contains(SelectedAddress)
End If
End Function
End Class

问题是 Canexecutechanged 仅在启动时触发,我实际上只想在选择列表框中的某些内容时启用删除按钮,并且我想通过 MVVM - ICommand 绑定(bind)方法完成它。您能否解释一下我哪里出错或错过了理解 ICommand 的实现。

谢谢你。

更新了我使用的 Relay iCommand 代码:
    Public Class RelayCommand
Implements ICommand
''' <summary>
''' A command whose sole purpose is to relay its functionality to other objects by invoking delegates. The default return value for the CanExecute method is 'true'.
''' </summary>
''' <remarks></remarks>

#Region "Declarations"
Private ReadOnly _CanExecute As Func(Of Boolean)
Private ReadOnly _Execute As Action
#End Region

#Region "Constructors"
Public Sub New(ByVal execute As Action)
Me.New(execute, Nothing)
End Sub

Public Sub New(ByVal execute As Action, ByVal canExecute As Func(Of Boolean))
If execute Is Nothing Then
Throw New ArgumentNullException("execute")
End If
_Execute = execute
_CanExecute = canExecute
End Sub
#End Region

#Region "ICommand"
Public Custom Event CanExecuteChanged As EventHandler Implements System.Windows.Input.ICommand.CanExecuteChanged

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

If _CanExecute IsNot Nothing Then
RemoveHandler CommandManager.RequerySuggested, value
End If
End RemoveHandler

RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
'This is the RaiseEvent block
'CommandManager.InvalidateRequerySuggested()
End RaiseEvent
End Event

Public Function CanExecute(ByVal parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
If _CanExecute Is Nothing Then
Return True
Else
Return _CanExecute.Invoke
End If
End Function

Public Sub Execute(ByVal parameter As Object) Implements System.Windows.Input.ICommand.Execute
_Execute.Invoke()
End Sub
#End Region
End Class

大部分代码都是副本,但我通过下面的评论理解了它的工作原理。

最佳答案

正如 Raul Otaño 所指出的,您可以提高 CanExecuteChanged .但是,并非所有 MVVM 框架都提供 RaiseCanExecuteChanged方法。还值得注意的是,实际事件CanExecuteChanged必须在 UI 线程上调用。因此,如果您期望模型中某个线程的回调,则需要将其调用回 UI 线程,如下所示:

    public void RaiseCanExecuteChanged()
{
if (CanExecuteChanged != null)
{
Application.Current.Dispatcher.Invoke((Action)(() => { CanExecuteChanged(this, EventArgs.Empty); }));
}
}

我强烈建议不要调用 CommandManager.InvalidateRequerySuggested()因为虽然这在功能上有效,并且适用于小型应用程序,但它是不分青红皂白的,并且可能会重新查询每个命令!在具有大量命令的大型系统中,这可能非常非常慢!

关于wpf - ICommand CanExecuteChanged 未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19657463/

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