简体   繁体   中英

WPF Multibinding - Need to use Relaycommand

So, I have an element which has a command with 2 parameters to pass.

I previously did this with a snippet of code I found, but cannot for the life of me remember how to do it or find it again.

So, here is the multivalueconverter I previously created:

public class MultiValueConverter : IMultiValueConverter
{

    public object Convert(object[] values, Type targetType,
    object parameter, CultureInfo culture)
    {
        return values.Clone();
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        return (value as string).Split(' ');
    }

}

Now, I need to just assign the function I want to call in the ICommand. I normally use a line similar to:

enemyPopupTooltip = new RelayCommand(param => this.EnemyPopupTooltipEx(param),null);

However, this wont work when its multivalue.How can I use my relaycommand to pass 2 parameters, using the multivalueconverter, into my function?

For reference, here is everything inside relaycommand class:

public class RelayCommand : ICommand
{
    /// <summary>
    /// Initializes a new instance of the <see cref="RelayCommand"/> class.
    /// </summary>
    /// <param name="execute">The execute.</param>
    public RelayCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="RelayCommand"/> class.
    /// </summary>
    /// <param name="execute">The execute.</param>
    /// <param name="canExecute">The can execute.</param>
    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");
        _execute = execute;
        _canExecute = canExecute;
    }

    /// <summary>
    /// Defines the method that determines whether the command can execute in its current state.
    /// </summary>
    /// <param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
    /// <returns>
    /// true if this command can be executed; otherwise, false.
    /// </returns>
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

    /// <summary>
    /// Occurs when changes occur that affect whether or not the command should execute.
    /// </summary>
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    /// <summary>
    /// Defines the method to be called when the command is invoked.
    /// </summary>
    /// <param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
    public void Execute(object parameter)
    {
        _execute(parameter);
    }

    /// <summary>
    /// Action
    /// </summary>
    private readonly Action<object> _execute;


    /// <summary>
    /// Predicate
    /// </summary>
    private readonly Predicate<object> _canExecute;

you said:

However, this wont work when its multivalue

This assumption is wrong. It does work!

When your multiconverter returns array of values, then this array is passed as a parameter to Command.Execute method.

new RelayCommand(EnemyPopupTooltipEx, null);

public void EnemyPopupTooltipEx(object parameter){
   var values = (object[])parameters;
}

however, this is very dirty approach. I guess you are passing some UIElement(s) to the command parameter. This is violation of viewmodel's responsibility. Consider moving code that need reference to UIElement to codebehind.

Just put your two parameters into one object. You could use any kind of collection or array, but perhaps the simplest option is to use the Tuple<T1, T2> Class in your IMultiValueConverter :

if (values != null && values.Length >= 2)
{
    Tuple<Type1, Type2> yourTwoValues = new Tuple<Type1, Type2>(values[0], values[1]);
    return yourTwoValues;
}

Then you can pass the Tuple to your ICommand as the parameter and extract the individual values at the other end.

Try with new Property, Do multibing in CommandParameter and Handle in ExecuteEnterCommand. like object[] arr = (object[])obj;

 public ICommand EnemyPopupTooltip
        {
            get
            {
                if (this.enemyPopupTooltip == null)
                {
                    this.enemyPopupTooltip = new RelayCommand<object>(this.ExecuteEnterCommand, this.CanExecuteEnterCommand);
                }

                return this.enemyPopupTooltip;
            }
        }


        private ICommand enemyPopupTooltip;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM