1

I want to implement click event using MVVM pattern. The code I have done is as follows:- Inside the xaml file:-

Added namespace

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

and then added

 <i:Interaction.Triggers>
    <i:EventTrigger EventName="Click">
        <i:InvokeCommandAction Command="{Binding ButtonClickCommand}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

and removed click event from button

inside xaml.vb page

   Public Sub New()
        InitializeComponent()
        Me.DataContext = New CoverageViewModel
    End Sub

inside my viewmodel page

  Public ReadOnly Property ButtonClickCommand() As ICommand
        Get
            Return New DelegateCommand(Of Object)(AddressOf ButtonClicked)
        End Get
    End Property
    Public Sub ButtonClicked(obj As Object)
        Dim class As New Myclass
        If (Globals.IsEdited = False) Then
            'My Code

        End If
    End Sub

But it is not working, please tell the changes I should make inside my code.

Thanks

rahul aggarwal
  • 143
  • 1
  • 11
  • You are returning a new command on each `Get` of your property. Define the property and set it once. – Cyral Jun 17 '15 at 12:42
  • Its a readonly property, Readonly property only have Get. Can you please help with the code – rahul aggarwal Jun 17 '15 at 12:45
  • You should instantiate the Command only once, and the return that instance every time. No need for a Set, this is all done in the Get. Though, that being said, this change alone will hardly make your code work... But I don't see anything wrong, other than that. – almulo Jun 17 '15 at 12:52
  • You could also handle the event in an Attached Property... see my answer to the [What's the best way to pass event to ViewModel?](http://stackoverflow.com/questions/21285577/whats-the-best-way-to-pass-event-to-viewmodel/21285863#21285863) for an example. – Sheridan Jun 17 '15 at 13:04

2 Answers2

0

You really want to be using relaycommand for this.

Begin by adding the following to your project:

Imports System.Windows.Input


''' <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>
Public Class RelayCommand
    Implements ICommand
#Region "Fields"

    Private ReadOnly _execute As Action(Of Object)
    Private ReadOnly _canExecute As Predicate(Of Object)

#End Region ' Fields

#Region "Constructors"

    ''' <summary>
    ''' Creates a new command that can always execute.
    ''' </summary>
    ''' <param name="execute">The execution logic.</param>
    Public Sub New(ByVal execute As Action(Of Object))
        Me.New(execute, Nothing)
    End Sub

    ''' <summary>
    ''' Creates a new command.
    ''' </summary>
    ''' <param name="execute">The execution logic.</param>
    ''' <param name="canExecute">The execution status logic.</param>
    Public Sub New(ByVal execute As Action(Of Object), ByVal canExecute As Predicate(Of Object))
        If execute Is Nothing Then
            Throw New ArgumentNullException("execute")
        End If

        _execute = execute
        _canExecute = canExecute
    End Sub

#End Region ' Constructors

#Region "ICommand Members"

    <DebuggerStepThrough> _
    Public Function CanExecute(ByVal parameter As Object) As Boolean Implements ICommand.CanExecute
        Return If(_canExecute Is Nothing, True, _canExecute(parameter))
    End Function

    Public Custom Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged
        AddHandler(ByVal value As EventHandler)
            AddHandler CommandManager.RequerySuggested, value
        End AddHandler
        RemoveHandler(ByVal value As EventHandler)
            RemoveHandler CommandManager.RequerySuggested, value
        End RemoveHandler
        RaiseEvent(ByVal sender As System.Object, ByVal e As System.EventArgs)
        End RaiseEvent
    End Event

    Public Sub Execute(ByVal parameter As Object) Implements ICommand.Execute
        _execute(parameter)
    End Sub

#End Region ' ICommand Members
End Class

Now in your xaml you put the following in the xaml describing your button

Command={Binding Path=MyButtonClickCommand}

Now in the viewmodel which your view is using as its datacontext add the following:

   Private _myButtonClickCommand As ICommand
    Public ReadOnly Property MyButtonClickCommand As ICommand
        Get
            if _myButtonClickCommand Is Nothing Then
                Dim myMyButtonClick As New Action(Of Object)(AddressOf MyButtonClick)
       _myButtonClickCommand = New RelayCommand(myMyButtonClick)
            End If
            Return _myButtonClickCommand
        End Get
    End Property
    Private Sub MyButtonClick(ByVal obj As Object)
        'Add code here to do want you want doing when the button is clicked
    End Sub

You can apply this principle to all sorts of things. I strongly suggest that you read Josh Smiths definitive article on this here

Dom Sinclair
  • 2,458
  • 1
  • 30
  • 47
  • still not working. Can you please help me with my code. Didn't understood the purpose of first code and also where should I use code Command={Binding Path=MyButtonClickCommand}, didn't understood. – rahul aggarwal Jun 17 '15 at 13:04
  • Remove all the xaml from your button dealing with interactions and just add the bit of xaml I placed at the top of the answer. Create a new class in your project called RelayCommand. Copy and paste the code from the answer into that. Finally add the last section of code into your viewmodel. Assuming that your viewmodel is your view datacontext it should work. – Dom Sinclair Jun 17 '15 at 16:17
0

Try To do with following code

 Dim _ButtonClickCommand As DelegateCommand(Of Object)
Public ReadOnly Property ButtonClickCommand() As DelegateCommand(Of Object)
    Get
        If _ButtonClickCommand Is Nothing Then
            _ButtonClickCommand = New DelegateCommand(Of Object) _
            (AddressOf OnButtonClickCommandExecute, AddressOf OnButtonClickCommandCanExecute)
        End If
        Return _ButtonClickCommand
    End Get
End Property

Sub OnButtonClickCommandExecute(ByVal parameter As Object)

     ''Your Button Click Logic
End Sub

Function OnButtonClickCommandCanExecute(ByVal parameter As Object) As Boolean
    Return true
End Function
Snehal
  • 1,070
  • 12
  • 20