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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/920172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:29:12  来源:igfitidea点击:

How do I pass the information from View to ViewModel with DelegateCommand?

wpfmvvmdelegatecommand

提问by Edward Tanguay

In my View, I have a button.

在我的视图中,我有一个按钮。

When the user clicks this button, I want to have the ViewModel save the context of the TextBlock in the database.

当用户单击此按钮时,我希望 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>

However, in my DelegateCommand in my ViewModel, the "Save()" method doesn't pass any arguments, so how do I get data from the view at that point?

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

回答by Matt Hamilton

Check out this MSDN article by Josh Smith. In it, he shows a variation of DelegateCommand that he calls RelayCommand, and the Execute and CanExecute delegates on RelayCommand accept a single parameter of type object.

查看Josh Smith 撰写的这篇 MSDN 文章。在其中,他展示了他称为 RelayCommand 的 DelegateCommand 的变体,并且 RelayCommand 上的 Execute 和 CanExecute 委托接受类型为 object 的单个参数。

Using RelayCommand you can pass information to the delegates via a CommandParameter:

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

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

Update

更新

Looking at this article, it appears that there is a generic version of DelegateCommand which accepts a parameter in a similar way. You might want to try changing your SaveCommand to a DelegateCommand<MyObject>and change your Save and CanSave methods so that they take a MyObject parameter.

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

回答by Matt Hamilton

here is the elegant way.

这是优雅的方式。

Give a name to your textbox, then bind the CommandParameter in the button to it's Text property:

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

回答by Carlos

In your VM:

在您的虚拟机中:

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

public ICommand SaveCmd{ get{ return _saveCmd } }

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

In you View, use CommandParameter like Matt's example.

在您的视图中,像 Matt 的示例一样使用 CommandParameter。

回答by Jeffrey Knight

You're asking about passing data via the button Command.

您正在询问通过按钮命令传递数据。

What you actually want, I think, is to bindyour Textbox's text to a public propertyin your ViewModel:

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

回答by ml_black

I'm not allowed to make comments yet, I guess. I'm responding to Carlos' suggestion because I tried it out. While it's a great idea, DelegateCommand would need to be modified in some way because otherwise you'll get this error: A field initializer cannot reference the non-static field, method, or property 'MyViewModel.Save(string)'.

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