Wpf 如何使用DelegateCommand将信息从视图传递到视图模型?

Wpf 如何使用DelegateCommand将信息从视图传递到视图模型?,wpf,mvvm,delegatecommand,Wpf,Mvvm,Delegatecommand,在我看来,我有一个按钮 当用户单击此按钮时,我希望ViewModel在数据库中保存TextBlock的上下文 <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top"> <TextBlock Text="{Binding FirstName}"/> <TextBox Text="Save this text to the database."/> <Button

在我看来,我有一个按钮

当用户单击此按钮时,我希望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的一个变体,他称之为RelayCommand,RelayCommand上的Execute和CanExecute委托接受object类型的单个参数

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

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

更新

现在来看,似乎有一个DelegateCommand的通用版本,它以类似的方式接受参数。您可能希望尝试将SaveCommand更改为
DelegateCommand
,并更改Save和CanSave方法,以便它们采用MyObject参数。

在VM中:

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

public ICommand SaveCmd{ get{ return _saveCmd } }

public void Save(string s) {...}
private DelegateCommand\u saveCmd=new DelegateCommand(Save);
公共ICommand SaveCmd{get{return}
公共无效保存(字符串s){…}

在您的视图中,使用CommandParameter,如Matt的示例。

您询问的是如何通过按钮命令传递数据

我认为,您真正想要的是将文本框的文本绑定到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;
}

公共字符串名{get;set;}
...
私有void Save()
{
//textBox的文本绑定到-->this.FirstName;
}

这里是优雅的方式

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

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

我实际上通过将文本框绑定到ViewModel属性(INotifyPropertyChanged)来解决了我的问题,当然Save()命令可以访问该属性的值,但您的建议非常有趣,有一个特定的(相当常见的)用例,Matt的解决方案肯定会胜过访问单独的绑定值:从
ItemsControl
中执行的命令。这里,一个按钮,比如,在一个
列表视图中
可以使用它的
数据上下文
作为一个参数,并且点击按钮的项目会随命令一起传递。很难确定许多项中哪些项的按钮被单击了。请注意,通用的
DelegateCommand
有一个重要的限制(直到运行时才被选中-编译器不会抱怨):不能使用值类型作为参数。官方建议是使用可为空的值类型(这是允许的),并在使用前检查它是否包含值(-请参阅“备注”部分)。这是我通常做的,因为TextBox值已绑定到viewmodel中的属性。无需将其作为参数传递给命令。如果您仅将文本用于一个目的,则将其作为参数传递更有意义(代码可读性)。例如,向VM传递激活密钥。这不是一个完整的答案,但这为我指明了使用CommandParameter和指定DelegateCommand类型的正确方向。谢谢
<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>