Как передать информацию из View в ViewModel с DelegateCommand?
В моем представлении у меня есть кнопка.
Когда пользователь нажимает эту кнопку, я хочу, чтобы ViewModel сохранял контекст TextBlock в базе данных.
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBlock Text="{Binding FirstName}"/>
<TextBox Text="Save this text to the database."/>
<Button Content="Save" Command="{Binding SaveCommand}"/>
</StackPanel>
Однако в моей функции DelegateCommand в моей модели ViewModel метод "Сохранить()" не передает никаких аргументов, так как я могу получить данные из представления в этой точке?
#region DelegateCommand: Save
private DelegateCommand saveCommand;
public ICommand SaveCommand
{
get
{
if (saveCommand == null)
{
saveCommand = new DelegateCommand(Save, CanSave);
}
return saveCommand;
}
}
private void Save()
{
TextBox textBox = ......how do I get the value of the view textbox from here?....
}
private bool CanSave()
{
return true;
}
#endregion
Ответы
Ответ 1
Ознакомьтесь с этой статьей MSDN Джошем Смитом. В нем он показывает вариант DelegateCommand, который он называет RelayCommand, а делегаты Execute и CanExecute в RelayCommand принимают один параметр объекта типа.
Используя RelayCommand, вы можете передавать информацию делегатам через CommandParameter:
<Button Command="{Binding SaveCommand}"
CommandParameter="{Binding SelectedItem,Element=listBox1}" />
Обновление
Рассматривая эту статью, похоже, что существует общая версия DelegateCommand, которая принимает параметр аналогичным образом. Возможно, вы захотите изменить свой SaveCommand на DelegateCommand<MyObject>
и изменить методы сохранения и CanSave, чтобы они принимали параметр MyObject.
Ответ 2
вот элегантный способ.
Дайте имя своему текстовому полю, затем привяжите CommandParameter в кнопке к нему. Свойство "Текст":
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBlock Text="{Binding FirstName}"/>
<TextBox x:Name="ParameterText" Text="Save this text to the database."/>
<Button Content="Save" Command="{Binding SaveCommand}"
CommandParameter="{Binding Text, ElementName=ParameterText}"/>
</StackPanel>
Ответ 3
В вашей виртуальной машине:
private DelegateCommand<string> _saveCmd = new DelegateCommand<string>(Save);
public ICommand SaveCmd{ get{ return _saveCmd } }
public void Save(string s) {...}
В представлении View используйте CommandParameter, например, пример Matt.
Ответ 4
Вы спрашиваете о передаче данных с помощью кнопки Command.
То, что вы на самом деле хотите, я думаю, это привязать текст вашего текстового текста к общедоступному свойству в вашей модели ViewModel:
<!-- View: TextBox text is bound to the FirstName property in your ViewModel -->
<TextBox Text="{Binding Path=FirstName}" />
<Button Command="{Binding SaveCommand}"/>
<!-- ViewModel: Expose a property for the TextBox to bind to -->
public string FirstName{ get; set; }
...
private void Save()
{
//textBox text is bound to --> this.FirstName;
}
Ответ 5
Я не могу оставлять комментарии еще, я думаю. Я отвечаю на предложение Карлоса, потому что я попробовал это. Хотя это отличная идея, DelegateCommand нужно будет каким-то образом изменить, потому что в противном случае вы получите эту ошибку:
Инициализатор поля не может ссылаться на нестатическое поле, метод или свойство "MyViewModel.Save(string)".