Xaml, событие нажатия кнопки запускается перед командой? - PullRequest
0 голосов
/ 05 мая 2018

(сейчас я изучаю 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="&#xE105;" 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. Так что мой проект в любом случае работает нормально, но он очень пахнет.

  1. Как правильно решить эту проблему? Использовать конвертер? Сейчас я пытаюсь использовать конвертер для передачи CommandParameter, но застрял. SaveCommand нужен Person объект в качестве параметра, а объект Person нуждается в двух данных (имя и возраст). как я могу передать два параметра в конвертер? используя Tuple? (

  2. С любопытством, событие щелчка всегда запускается перед командой?

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

В вашей команде вы можете использовать параметр параметра (без phun)

public void Execute(object parameter)
{
    viewModel.Reply1 = new Models.Reports.Reply();
    viewModel.ShowList = false;
}

В вашем XAML вы должны указать этот параметр следующим образом:

    <Button Command="{Binding UpdateCommand}" CommandParameter="TheParameterYouWantoToUseInTheExecute"
0 голосов
/ 05 мая 2018

Установить объект модели представления из конструктора в коде класса.

Вы не должны использовать и Command, и Click-event.

...