【发布时间】:2018-05-05 05:00:02
【问题描述】:
(现在我正在学习 MVVM)我正在尝试使用来自 UI 的输入数据更新当前数据(在视图模型中)。 但问题是 ViewModel 不知道 View。这样我就无法访问 UI 中的输入数据(如 TextBox.Text)。
(下)在MainPage.xaml中包含两个TextBoxes来获取输入数据
和一个保存输入数据的按钮
<StackPanel>
<TextBox x:Name="NameTextBox" Margin="10" Header="Name text box" />
<TextBox x:Name="AgeTextBox" Margin="10" Header="Age text box"/>
<StackPanel Orientation="Horizontal">
<Button x:Name="SaveButton" Content="" FontFamily="Segoe MDL2 Assets" Margin="30,10"
CommandParameter="{x:Bind ViewModel.CreatedPerson, Mode=OneWay}"
Command="{x:Bind ViewModel.SaveCommand}"
Click="SaveButton_Click"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="20">
<TextBlock Text="{x:Bind ViewModel.Person.Name, Mode=OneWay}" />
<TextBlock Text="{x:Bind ViewModel.Person.Age, Mode=OneWay}" />
</StackPanel>
</StackPanel>
NameTextBox 和 AgeTextBox 保存输入数据,直到点击 SaveButton。
(Person 是具有姓名和年龄属性的纯数据模型)
注意:
SaveButton上面有Command和Click事件
(下)MainPageViewModel.cs中包含两个属性和命令逻辑
public class MainPageViewModel : ViewModelBase
{
public Person Person
{
get => _person;
set { Set(nameof(Person), ref _person, value); }
}
private Person _person;
public Person CreatedPerson
{
get => _createdPerson;
set { Set(nameof(CreatedPerson), ref _createdPerson, value); }
}
private Person _createdPerson;
public MainPageViewModel()
{
Person = new Person();
}
private RelayCommand<Person> _saveCommand;
public RelayCommand<Person> SaveCommand
{
get
{
return _saveCommand
?? (_saveCommand = new RelayCommand<Person>(
p =>
{
Person.Name = p.Name;
Person.Age = p.Age;
}));
}
}
}
MainPageViewModel 包含 Person 和 CreatedPerson 属性。
Person 属性包含当前数据。
CreatedPerson 属性包含来自 UI 的临时数据。
如果SaveButton被点击Person属性被更新。
(下)在MainPage.xaml.cs(代码隐藏文件)中有ViewModel和SaveButton_Click事件
public sealed partial class MainPage : Page
{
private readonly MainPageViewModel ViewModel = new MainPageViewModel();
public MainPage()
{
this.InitializeComponent();
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
var newPerson = new Model.Person
{
Name = NameTextBox.Text,
Age = Convert.ToInt32(AgeTextBox.Text)
};
ViewModel.CreatedPerson = newPerson;
}
}
SaveButton_Click 事件从 TextBox 中获取数据并将它们保存在 ViewModel 中。
我的问题是如何将 UI 数据(在 TextBox 中)作为 SaveCommand 的参数传递? MainPageViewModel 不知道视图中的文本框。
为了解决这个问题,我在代码隐藏中创建了SaveButton_Click 事件来访问 TextBoxes 数据。 SaveButton_Click 从 TextBoxes 中获取数据并将它们保存到 ViewModel(在 CreatedPerson 属性中)。
设置CreatedPerson 后,ViewModel 中的SaveCommand 执行更新Person 属性。
因此,当单击SaveButton 时,SaveButton_Clicked 事件在SaveCommand 之前触发。所以我的项目无论如何都运行良好,但它闻起来很香。
如何以正确的方式解决此问题? 使用转换器? 现在我正在尝试使用转换器传递
CommandParameter,但卡住了。SaveCommand需要Person对象作为参数,Person 对象需要两个数据(姓名和年龄)。如何将两个参数传递给转换器?使用Tuple? :(奇怪的是,click 事件总是在 Command 之前触发?
【问题讨论】: