Передача двух параметров команды с помощью привязки WPF
у меня есть команда, которую я выполняю из моего XAML-файла, используя следующий стандартный синтаксис:
<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand}"/>
это работало нормально, пока я не понял, что мне нужны две части информации из представления, чтобы сделать эту операцию полной так, как ожидают пользователи (ширина и высота холста специально).
похоже, что можно передать массив в качестве аргумента моей команде, но я не вижу способа указать привязку к моим двум холстам свойства в CommandParameter:
<Button Content="Zoom"
Command="{Binding MyViewModel.ZoomCommand"
CommandParameter={Binding ElementName=MyCanvas, Path=Width}"/>
Как передать ширину и высоту моей команде? Не похоже, что это возможно с помощью команд из XAML, и мне нужно подключить обработчик щелчка в моем codebehind, чтобы получить эту информацию для передачи в мой метод масштабирования.
4 ответа:
во-первых, если вы делаете MVVM, вы обычно будете иметь эту информацию, доступную для вашей виртуальной машины через отдельные свойства, связанные с представлением. Это избавляет вас от необходимости передавать какие-либо параметры в ваши команды.
тем не менее, вы также можете выполнить множественную привязку и использовать конвертер для создания параметров:
<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand"> <Button.CommandParameter> <MultiBinding Converter="{StaticResource YourConverter}"> <Binding Path="Width" ElementName="MyCanvas"/> <Binding Path="Height" ElementName="MyCanvas"/> </MultiBinding> </Button.CommandParameter> </Button>
в свой конвертер:
public class YourConverter : IMultiValueConverter { public object Convert(object[] values, ...) { return values.Clone(); } ... }
затем, в логике выполнения команды:
public void OnExecute(object parameter) { var values = (object[])parameter; var width = (double)values[0]; var height = (double)values[1]; }
в преобразователе выбранного решения следует добавить значения.Clone () в противном случае параметры в команде end null
public class YourConverter : IMultiValueConverter { public object Convert(object[] values, ...) { return values.Clone(); } ... }
используйте Кортеж в конвертере, а в OnExecute верните объект параметра обратно в кортеж.
public class YourConverter : IMultiValueConverter { public object Convert(object[] values, ...) { Tuple<string, string> tuple = new Tuple<string, string>( (string)values[0], (string)values[1]); return (object)tuple; } } // ... public void OnExecute(object parameter) { var param = (Tuple<string, string>) parameter; }
об использовании кортежа в конвертере, было бы лучше использовать 'object' вместо 'string', так что он работает для всех типов объектов без ограничения 'string' объекта.
public class YourConverter : IMultiValueConverter { public object Convert(object[] values, ...) { Tuple<object, object> tuple = new Tuple<object, object>(values[0], values[1]); return tuple; } }
тогда логика выполнения команды может быть такой
public void OnExecute(object parameter) { var param = (Tuple<object, object>) parameter; // e.g. for two TextBox object var txtZip = (System.Windows.Controls.TextBox)param.Item1; var txtCity = (System.Windows.Controls.TextBox)param.Item2; }
и мульти-привязка с конвертером для создания параметров (с двумя объектами текстового поля)
<Button Content="Zip/City paste" Command="{Binding PasteClick}" > <Button.CommandParameter> <MultiBinding Converter="{StaticResource YourConvert}"> <Binding ElementName="txtZip"/> <Binding ElementName="txtCity"/> </MultiBinding> </Button.CommandParameter> </Button>