0

I am creating a UWP MVVM app. I have created ViewModel and View, I make it DataContext, and everything is working just fine with bindings.

I was able to invoke method that has no parameters. This is my XAML code in View:

<Button VerticalAlignment="Top" HorizontalAlignment="Right" Margin="50" Width="50" Height="50" Background="Transparent" BorderBrush="Transparent" Content="OK" FontSize="32" FontWeight="Bold" Foreground="White" Click="{x:Bind Path=ViewModel.ButtonMainClick, Mode=OneWay}"/> 

In ViewModel I have like this:

public void ButtonMainClick()
{
    // TO DO
}

And this works just fine.

Now I want to invoke some method that has parameters. But I am unable to do it this way. I saw on internet that there is a EventTriggerBehavior. But I am not sure how to use it and pass some parameters.

Any idea?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
user3239349
  • 877
  • 1
  • 12
  • 33

2 Answers2

0

Assuming that UWP and WPF binding work the same, you should bind your buttons to properties of type ICommand in your ViewModel. A common implementation of ICommand is the RelayCommand, which could look like this:

 public class RelayCommand : ICommand
    {
        private readonly Action _targetExecuteMethod;
        private readonly Func<bool> _targetCanExecuteMethod;
        public RelayCommand(Action executeMethod) => _targetExecuteMethod = executeMethod;

        public RelayCommand(Action executeMethod, Func<bool> canExecuteMethod)
        {
            _targetExecuteMethod = executeMethod;
            _targetCanExecuteMethod = canExecuteMethod;
        }
        public void RaiseCanExecuteChanged() => CanExecuteChanged(this, EventArgs.Empty);
        bool ICommand.CanExecute(object parameter) => _targetCanExecuteMethod?.Invoke() ?? _targetExecuteMethod != null;
        public event EventHandler CanExecuteChanged = delegate { };
        void ICommand.Execute(object parameter) => _targetExecuteMethod?.Invoke();
    }
    public class RelayCommand<T> : ICommand
    {
        private readonly Action<T> _targetExecuteMethod;
        private readonly Func<T, bool> _targetCanExecuteMethod;
        public RelayCommand(Action<T> executeMethod) => _targetExecuteMethod = executeMethod;
        public RelayCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
        {
            _targetExecuteMethod = executeMethod;
            _targetCanExecuteMethod = canExecuteMethod;
        }
        public void RaiseCanExecuteChanged() => CanExecuteChanged(this, EventArgs.Empty);
        bool ICommand.CanExecute(object parameter)
        {
            if (_targetCanExecuteMethod != null)
            {
                var tparm = (T)parameter;
                return _targetCanExecuteMethod(tparm);
            }
            return _targetExecuteMethod != null;
        }
        public event EventHandler CanExecuteChanged = delegate { };
        void ICommand.Execute(object parameter) => _targetExecuteMethod?.Invoke((T)parameter);
    }

For the View and ViewModel, take a look at this example: https://stackoverflow.com/a/53045098/9889260

If you want to use parameters. You just use the generic RelayCommand<T> where T is the type you want to pass as a parameter and also give your Excecute and CanExcecute(if you have one) methods T as your parameter.

Kind regards, mis

0

Event handlers using x:Bind can't take arbitrary arguments.

One simple solution is just to expose another method that makes the call for you. The method bound to the Click event has no parameters, but it just calls the method you need to execute.

[Edit] If you need to pass context from the control that generated the event, you can do that by adding the event signature and accessing the sender's DataContext and casting your ViewModel type.

void FuncThatDoesSomething(T1 arg1, T2 arg2,...)
{
  // do it
}

// function has to match the event handler signature 
void FuncThatIsBoundInXaml(object sender, RoutedEventArgs e)
{
  var vm = sender.DataContext as YourViewModelType;
  // call method with required args
  FuncThatDoesSomething(vm.SomeProperty, 42);
}
Peter Torr - MSFT
  • 11,824
  • 3
  • 18
  • 51