wpf 如何在 mvvm 命令中使用文本框的值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30321678/
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
How to use the value of textbox in mvvm commands
提问by Phil
I'm still figuring out mvvm and I want to make my app the right way by splitting up model viewmodel and view. In the past I always took the value of the textbox in the view directly by using mytextbox.Text.
我仍在研究 mvvm,我想通过拆分模型视图模型和视图来使我的应用程序以正确的方式运行。过去我总是通过使用mytextbox.Text直接获取视图中文本框的值。
I created a command in the viewmodel to add a new person to the network. but I can't get the values of the textboxes into the command in the viewmodel.
我在视图模型中创建了一个命令来向网络添加一个新人。但我无法将文本框的值放入视图模型中的命令中。
This is the code I have so far in model
这是我目前在模型中的代码
public class Person : INotifyPropertyChanged
{
public Person()
{ }
public Person(String FirstName)
{
this._firstName = FirstName;
}
public event PropertyChangedEventHandler PropertyChanged;
private string _firstName;
public string FirstName // the Name property
{
get { return this._firstName; }
set { this._firstName = value; NotifyPropertyChanged("FirstName"); }
}
}
in the viewmodel I have
在我有的视图模型中
public class NetworkViewModel: INotifyPropertyChanged
{
private ObservableCollection<Person> _networkList1 = new ObservableCollection<Person>();
public ObservableCollection<Person> NetworkList1 //Binds with the listbox
{
get { return _networkList1; }
set { _networkList1 = value; RaisePropertyChanged("NetworkList1"); }
}
public NetworkViewModel()
{
AddPersonCommand = new RelayCommand(AddPerson);
}
private ICommand _addPersonCommand;
public ICommand AddPersonCommand // Binding with view
{
get { return _addPersonCommand; }
set { _addPersonCommand = value; }
}
public void AddPerson(object obj)
{
if(cb_group.Text.ToUpper() == "PRIMARY")
{
_networkList1.Add(new Person(){ FirstName = tb_firstName.Text,});
}
}
in XAML
在 XAML 中
<TextBox x:Name="tb_firstName" Text="{Binding Path=FirstName}"/>
<Button x:Name="btn_add" Command="{Binding AddPersonCommand }"/>
What I would like is to make the value of tb_firstname and cb_group to be used in the viewmodel so I can make the command work. Thanks for all your help. I'm just learning as I go.
我想要的是在视图模型中使用 tb_firstname 和 cb_group 的值,以便我可以使命令工作。感谢你的帮助。我只是边走边学。
回答by emybob
ok so in your textbox you currently have:
好的,在您的文本框中,您目前拥有:
<TextBox x:Name="tb_firstName" Text="{Binding Path=FirstName}"/>
What this means is that it is looking for a property on your viewmodel called FirstName, so you will need a add a string property to your viewmodel for it. Then when you set the FirstName on the new Person, you simply set it to the property.
这意味着它正在您的视图模型上寻找一个名为 FirstName 的属性,因此您需要为其添加一个字符串属性到您的视图模型。然后,当您在新 Person 上设置 FirstName 时,只需将其设置为属性即可。
new Person() { FirstName = this.FirstName };
For binding a combobox, it will need an itemsSource - this is the collection of items, in your case the NetworkList1 to be shown. As its binding to a list of objects you will also need to set the DisplayMemberPath - this is the name of the property you want to be shown in the combo. You will also need to bind the SelectedItem property and create a property in your viewmodel to store it. This is how you know which item in your list is currently selected.
为了绑定一个组合框,它需要一个 itemsSource - 这是项目的集合,在你的情况下是 NetworkList1 要显示。作为它与对象列表的绑定,您还需要设置 DisplayMemberPath - 这是您希望在组合中显示的属性的名称。您还需要绑定 SelectedItem 属性并在您的视图模型中创建一个属性来存储它。这就是您如何知道当前选择了列表中的哪个项目。
<Combobox ItemsSource={Binding Path=NetworkList1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}
SelectedItem = {Binding Path= SelectedPerson, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}
DisplayMemberPath=FirstName/>
viewModel:
视图模型:
public Person SelectedPerson
{
//put in get/set/propertychanged
}
public string FirstName
{
//put in get/set/propertychanged
}
回答by MajkeloDev
You need to add a CommandParameter and bind it to particualr Element.(in Your case tb_firstname.
您需要添加一个 CommandParameter 并将其绑定到特定的元素。(在您的情况下为 tb_firstname。
Version for TextBox:
文本框版本:
<Button Command="{Binding AddPersonCommand } CommandParameter="{Binding ElementName=tb_firstname, Path=Text"/>
EDIT. Version for ComboBox:
编辑。组合框版本:
<Button Command="{Binding AddPersonCommand } CommandParameter="{Binding ElementName=yourComboBox, Path=SelectedItem.Value"/> // or just SelectedItem
EDIT2 from (Multiple command parameters wpf button object)
EDIT2 来自(多个命令参数 wpf 按钮对象)
<Button Content="MultiBindingExample" Command="{Binding MyCommand}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource MyMultiConverter}">
<Binding Path="..." ElementName="MyTextBox"/>
<Binding Path="..." ElementName="MySomethingElse"/>
</MultiBinding>
</Button.CommandParameter>
回答by Daniel Slater
What you should be doing is in the AddPerson method rather than looking to value in the controls(cb_group.Text) use the values those controls are bound to. The binding should by default here be 2 way. So when the user changes the value it will automatically be updated in your model/viewmodel. If this isn't happening then the problem is with your databindings and you should look to see if you have any databinding errors in your console output.
您应该做的是在 AddPerson 方法中,而不是在控件中查找值(cb_group.Text)使用这些控件绑定到的值。默认情况下,这里的绑定应该是 2 种方式。因此,当用户更改值时,它会自动在您的模型/视图模型中更新。如果这没有发生,那么问题出在您的数据绑定上,您应该查看控制台输出中是否有任何数据绑定错误。

