如何使用DelegateCommand将信息从View传递到ViewModel?

Edw*_*uay 12 wpf mvvm 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>
Run Code Online (Sandbox Code Playgroud)

但是,在我的ViewModel中的DelegateCommand中,"Save()"方法不传递任何参数,那么如何从视图中获取数据呢?

#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's textbox from here?....
}

private bool CanSave()
{
    return true;
}
#endregion
Run Code Online (Sandbox Code Playgroud)

Mat*_*ton 19

查看Josh Smith撰写的这篇MSDN文章.在其中,他显示了一个DelegateCommand的变体,他调用了RelayCommand,而RelayCommand上的Execute和CanExecute委托接受了一个object类型的参数.

使用RelayCommand,您可以通过CommandParameter将信息传递给代理:

<Button Command="{Binding SaveCommand}" 
        CommandParameter="{Binding SelectedItem,Element=listBox1}" />
Run Code Online (Sandbox Code Playgroud)

更新

看看这篇文章,似乎有一个通用版本的DelegateCommand,它以类似的方式接受一个参数.您可能希望尝试将SaveCommand DelegateCommand<MyObject>更改为a 并更改Save和CanSave方法,以便它们采用MyObject参数.

  • 我实际上通过将TextBox绑定到ViewModel属性(INotifyPropertyChanged)解决了我的问题,当然Save()命令可以访问它的值,但是你的建议非常有趣,会检查它们. (2认同)

小智 13

这是优雅的方式.

为文本框命名,然后将按钮中的CommandParameter绑定到它的Text属性:

<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>
Run Code Online (Sandbox Code Playgroud)


Car*_*los 11

在您的VM中:

private DelegateCommand<string> _saveCmd = new DelegateCommand<string>(Save);

public ICommand SaveCmd{ get{ return _saveCmd } }

public void Save(string s) {...}
Run Code Online (Sandbox Code Playgroud)

在View中,使用CommandParameter,就像Matt的例子一样.


Jef*_*ght 5

您正在询问是否通过按钮Command传递数据.

我认为你真正想要的是 Textbox的文本绑定到ViewModel中的公共属性:

<!-- View: TextBox's 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's text is bound to --> this.FirstName;
}
Run Code Online (Sandbox Code Playgroud)