(Now I'm Studying MVVM) I'm trying update current data(in a view model) with input data from UI. But the problem is ViewModel doesn't know about the View. So that I can't access to input data in a UI (like TextBox.Text).
(below) In MainPage.xaml contains two TextBoxes to get input data
and a Button to Save input data
<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 and AgeTextBox holds input data until SaveButton is clicked.
(Person is plain data model with name and age properties)
be aware :
SaveButtonabove hasCommandandClickevent both
(below) In MainPageViewModel.cs contains two properties and Command logic
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 contains Person and CreatedPerson properties.
Person property contains current data.
CreatedPerson property contains temporary data from UI.
If SaveButton is clicked Person property is updated.
(below) In MainPage.xaml.cs (code-behind file) has ViewModel and SaveButton_Click event
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 event gets data from TextBoxes and save them in a ViewModel.
My Question is how can I pass UI data(in a TextBox) as a parameter of SaveCommand? MainPageViewModel don't know about TextBoxes in the view.
To solve this problem, I create SaveButton_Click event in code-behind to access TextBoxes data. SaveButton_Click gets data from TextBoxes and Save them to The ViewModel(at CreatedPerson property).
After CreatedPerson is set, SaveCommand in the ViewModel executed to update Person property.
As a result, when the SaveButton is clicked, SaveButton_Clicked event fires before SaveCommand. So my project works fine anyway, But it smells a lot.
How can I solve this problem in a right way? Use converter? Now I'm trying to Use converter to pass
CommandParameter, but stuck.SaveCommandneedPersonobject as a parameter, and Person object need two data(name and age). how can I pass two parameter to a converter? usingTuple? :(With curiousity, click event always fired before Command?