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

时间:2009-05-28 10:21:01

标签: 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>

但是,在我的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

5 个答案:

答案 0 :(得分:19)

结帐this MSDN article by Josh Smith。在其中,他显示了一个DelegateCommand的变体,他调用了RelayCommand,而RelayCommand上的Execute和CanExecute委托接受了一个object类型的参数。

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

<Button Command="{Binding SaveCommand}" 
        CommandParameter="{Binding SelectedItem,Element=listBox1}" />

<强>更新

查看this article,看来有一个通用版本的DelegateCommand以类似的方式接受参数。您可能想尝试将SaveCommand更改为DelegateCommand<MyObject>并更改Save和CanSave方法,以便它们采用MyObject参数。

答案 1 :(得分:12)

这是优雅的方式。

为文本框命名,然后将按钮中的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>

答案 2 :(得分:10)

在你的虚拟机中:

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

public ICommand SaveCmd{ get{ return _saveCmd } }

public void Save(string s) {...}

在你的View中,使用像Matt一样的CommandParameter。

答案 3 :(得分:5)

您要求通过按钮Command传递数据。

我认为您实际想要的是的文本绑定到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;
}

答案 4 :(得分:1)

我猜我还不准发表评论。我正在回应卡洛斯的建议,因为我试了一下。虽然这是一个好主意,但DelegateCommand需要以某种方式进行修改,否则您将收到此错误: 字段初始值设定项不能引用非静态字段,方法或属性“MyViewModel.Save(string)”。