2015-07-03 8 views
1

Итак, у меня есть элемент, который имеет команду с двумя параметрами для передачи.WPF Multibinding - необходимо использовать Relaycommand

Я ранее делал это с фрагментом кода, который я нашел, но не могу на всю жизнь помнить, как это сделать или найти его снова.

Итак, вот multivalueconverter я уже создан:

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(' '); 
    } 

} 

Теперь мне нужно просто назначить функцию, я хочу позвонить в ICommand. Обычно я использую похожую строку:

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

Однако, это не будет работать, когда его multivalue.How я могу использовать мой RelayCommand передать 2 параметра, используя multivalueconverter, в мою функцию?

Для справки, здесь есть все, что внутри класса RelayCommand:

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; 
+0

http://stackoverflow.com/questions/1350598/passing-two-command-parameters-using-a-wpf-binding – MajkeloDev

+0

Это связано вопрос не показывает, что написано внутри станут назначенные MyViewModel.ZoomCommand, которые это то, с чем я сталкиваюсь :( – pingu2k4

+0

Второй apporach: Не удается привязать требуемые параметры к некоторому свойству ViewModel? Тогда вы просто вызовете свойства VM в своем методе – MajkeloDev

ответ

2

вы сказали:

Однако, это не будет работать, когда его многозначным

Это предположение неверно. Он работает!

Когда ваш мультиконвертер возвращает массив значений, этот массив передается как параметр в метод Command.Execute.

new RelayCommand(EnemyPopupTooltipEx, null); 

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

Однако, это очень грязный подход. Я думаю, вы передаете некоторые элементы UIElement (ов) в параметр команды. Это является нарушением ответственности viewmodel. Рассмотрим движущийся код, который должен ссылаться на UIElement на codebehind.

+0

Я знаю, что это грязный подход, но в некоторой ситуации мы должны сделать. Например, если Я хочу обновить свой datagrid, тогда нам нужно отправить элемент UIElement. –

+0

вам не нужно отправлять элемент пользовательского интерфейса в viewmodel, поверьте мне.Это оффтоп, но если вам интересно, как сделать чистый путь, создайте новый вопрос и сообщите мне, добавив здесь комментарий. – Liero

+0

Добавлен новый qestion (как обновить мой DataGrid с помощью MVVM) –

0

Просто положите два параметра в один объект. Вы можете использовать любой вид коллекции или массива, но, возможно, самый простой вариант заключается в использовании Tuple<T1, T2> Class в вашем IMultiValueConverter:

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

Затем вы можете передать Tuple к вашему ICommand в качестве параметра и извлечения отдельных значений на другой конец.

+0

ОК, спасибо. Могла ли моя релейная команда выглядеть в этом случае по-идинично? – pingu2k4

+0

Да. Метод 'RelayCommand.Execute' имеет« объектный параметр », а« Tuple »- это« объект », поэтому вы можете передать его как параметр. – Sheridan

0

Попробуйте использовать новое свойство, сделайте мультибинг в CommandParameter и обработайте в ExecuteEnterCommand. как 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;