Xaml,按钮的点击事件在命令之前运行?

时间:2018-05-05 05:00:02

标签: c# xaml mvvm uwp-xaml

(现在我正在学习MVVM)我尝试使用来自UI的输入数据更新当前数据(在视图模型中)。 但问题是ViewModel对View不了解。这样我就无法访问UI中的输入数据(如TextBox.Text)。

(下面)在MainPage.xaml中包含两个TextBox来获取输入数据 和一个保存输入数据的按钮

<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>

NameTextBoxAgeTextBox保留输入数据,直到点击SaveButton为止。

Person是具有名称和年龄属性的普通数据模型)

  

请注意:上面的SaveButton包含CommandClick个事件

(下)在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包含PersonCreatedPerson属性。 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事件从TextBoxes获取数据并将其保存在ViewModel中。

我的问题是如何将UI数据(在TextBox中)作为SaveCommand的参数传递? MainPageViewModel在视图中不了解TextBoxes。

要解决此问题,我在代码隐藏中创建SaveButton_Click事件以访问TextBoxes数据。 SaveButton_Click从TextBoxes获取数据并将它们保存到ViewModel(在CreatedPerson属性中)。

设置CreatedPerson后,ViewModel中的SaveCommand会执行以更新Person属性。

因此,点击SaveButton后,SaveButton_Clicked事件会在SaveCommand之前触发。所以我的项目无论如何都能正常工作,但它闻起来很多。

  1. 如何以正确的方式解决此问题? 使用转换器? 现在我尝试使用转换器传递CommandParameter,但卡住了。 SaveCommand需要Person个对象作为参数,而Person对象需要两个数据(名称和年龄)。如何将两个参数传递给转换器?使用Tuple? :(

  2. 奇怪的是,Click事件总是在命令之前触发?

2 个答案:

答案 0 :(得分:0)

从类后面的代码中的构造函数设置视图模型对象。

您不应同时使用Command和Click事件。

答案 1 :(得分:0)

在您的命令中,您可以使用参数参数(无意图)

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

在您的XAML中,您将提供该参数:

    <Button Command="{Binding UpdateCommand}" CommandParameter="TheParameterYouWantoToUseInTheExecute"
相关问题