(сейчас я изучаю MVVM) Я пытаюсь обновить текущие данные (в модели представления) входными данными из пользовательского интерфейса.
Но проблема в том, что ViewModel не знает о View. Так что я не могу получить доступ к входным данным в пользовательском интерфейсе (например, TextBox.Text).
(ниже) В MainPage.xaml
содержится два текстовых поля для получения входных данных.
и кнопка для сохранения входных данных
<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
содержит временные данные из пользовательского интерфейса.
При нажатии 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
Событие получает данные из TextBoxes и сохраняет их в ViewModel.
Мой вопрос: как я могу передать данные пользовательского интерфейса (в TextBox) в качестве параметра SaveCommand
? MainPageViewModel
не знаю о TextBoxes в представлении.
Чтобы решить эту проблему, я создаю событие SaveButton_Click
в коде для доступа к данным TextBoxes. SaveButton_Click
получает данные из TextBoxes и сохраняет их в ViewModel (в свойстве CreatedPerson).
После установки CreatedPerson
, SaveCommand
в ViewModel выполняется для обновления свойства Person
.
В результате при нажатии SaveButton
событие SaveButton_Clicked
срабатывает до SaveCommand
. Так что мой проект в любом случае работает нормально, но он очень пахнет.
Как правильно решить эту проблему?
Использовать конвертер?
Сейчас я пытаюсь использовать конвертер для передачи CommandParameter
, но застрял.
SaveCommand
нужен Person
объект в качестве параметра, а объект Person нуждается в двух данных (имя и возраст). как я могу передать два параметра в конвертер? используя Tuple
? (
С любопытством, событие щелчка всегда запускается перед командой?