ICommand CanExecuteChanged无法更新 [英] ICommand CanExecuteChanged not updating

查看:95
本文介绍了ICommand CanExecuteChanged无法更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试MVVM模式的基本级别,并因ICommand CanExecute更改而感到震惊.我具有XAML绑定,如下所示:

I am trying for MVVM pattern basic level and got struck at ICommand CanExecute changed. I have XAML binding as follows:

    <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

我的ModelView:

My ModelView:

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绑定方法来完成它.您能解释我哪里出错了,或者错过了解ICommand的实现.

The problem is that the Canexecutechanged is firing only at start, I actually want to get the delete button enabled only when something in the listbox is selected, and I want to get it done by MVVM - ICommand binding method. Could you please explain where i went wrong or miss understood the ICommand implementation.

谢谢.

我使用的更新的Relay iCommand代码:

Updated Relay iCommand code I use:

    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

大多数代码是副本,但我理解以下注释的工作方式.

Most of the code is a copy, but I understood the working by below comments.

推荐答案

在ICommand实现中,必须具有触发事件CanExecuteChanged的某些方法,例如RiseCanExecuteChanged.然后,列表中的所选项目每次更改时,在您的视图模型中都将根据所需命令执行RaiseCanExecuteChanged.我建议您以任何方式使用任何通用命令,例如GalaSoft MVVMLite库的RelayCommandDelegateCommand的任何实现. 希望这会有所帮助...

You must have in your ICommand implementation some method like RiseCanExecuteChanged that fires the event CanExecuteChanged. Then every time that the selected item in the list changed, in your view model you execute the RaiseCanExecuteChanged from the command you want. Any way I suggest you to use any generic command, like the RelayCommand of GalaSoft MVVMLite library, or any implementation of DelegateCommand. Hope this helps...

这篇关于ICommand CanExecuteChanged无法更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆