Как получить поля формы в Xamarin Forms от нажатия кнопки - PullRequest
0 голосов
/ 22 октября 2019

Я пытаюсь получить значения полей в представлении в настройке MVVM одним нажатием кнопки с помощью интерфейса ICommand. Конечная цель - захватить эти поля одним нажатием кнопки, чтобы затем сохранить эти поля в БД SQLite. Я предоставляю представление, программный код и ViewModel, которые имеют те же поля, что и модель, чтобы дать полную картину, потому что я ищу, как они все сочетаются друг с другом, и нигде не могу найти хороший пример. Множество ссылок, ведущих на страницу MSDN о создании часов, но это не сильно помогает в форме отправки типа задачи.

Вот представление:

<?xml version="1.0" encoding="UTF-8"?>
 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="TermManager.Views.AddCourseView">
   <ContentPage.Content>
     <ScrollView>
        <StackLayout>
            <Label Text="Add Course" VerticalOptions="Center" HorizontalTextAlignment="Center" IsVisible="true" FontSize="Large" FontAttributes="Bold" TextColor="DarkBlue" Margin="10" />
            <Entry x:Name="CourseTitle" Placeholder="Course Title" Margin="3" />
            <Label Margin="3">Start Date</Label>
            <DatePicker x:Name="CourseStartDate" Margin="3" />
            <Label Margin="3">End Date</Label>
            <DatePicker x:Name="CourseEndDate" Margin="3" />
            <Picker x:Name="CourseStatus" Title="Course Status" Margin="3" TitleColor="DarkBlue">
                <Picker.ItemsSource>
                    <x:Array Type="{x:Type x:String}">
                        <x:String>in progress</x:String>
                        <x:String>completed</x:String>
                        <x:String>dropped</x:String>
                        <x:String>plan to take</x:String>
                    </x:Array>
                </Picker.ItemsSource>
            </Picker>
            <Entry x:Name="ProfessorName" Placeholder="Professor's Name" />
            <Entry x:Name="ProfessorPhone" Placeholder="Professor's Phone" />
            <Entry x:Name="ProfessorEmail" Placeholder="Professor's Email" />
            <Button x:Name="SaveCourseButton" Command="{Binding SaveCommand}" Text="Save" BackgroundColor="DarkBlue" TextColor="White" Margin="3" />
            <Button Text="Cancel" BackgroundColor="DarkRed" TextColor="White" Margin="3" Clicked="CancelCourseAddition" />
        </StackLayout>
    </ScrollView>
</ContentPage.Content>

Код сзади:

using System;
using Xamarin.Forms;
using TermManager.Models;
using TermManager.ViewModels;
using System.Collections.Generic;

namespace TermManager.Views
{
public partial class AddCourseView : ContentPage
{
    public int TermId { get; set; }

    private AddCourseViewModel viewModel = new AddCourseViewModel();

    public AddCourseView()
    {
        InitializeComponent();
        BindingContext = viewModel;
    }

    protected async void CancelCourseAddition(object sender, EventArgs args)
    {
        await Navigation.PopAsync();
    }

    async void SaveButtonClicked(object sender, SelectedItemChangedEventArgs args)
    {
        var vm = sender as AddCourseViewModel;

        Course course = new Course
        {
            CourseStatus = vm.CourseStatus,
            CourseTitle = vm.CourseTitle,
            StartCourseDate = vm.StartCourseDate,
            EndCourseDate = vm.EndCourseDate,
            ProfessorEmail = vm.ProfessorEmail,
            ProfessorName = vm.ProfessorName,
            ProfessorPhone = vm.ProfessorPhone,
            TermId = vm.TermId
        };

        //viewModel.SaveNewTerm(course);
        await Navigation.PopAsync();
    }
}
}

Просмотр модели:

using System;
using Xamarin.Forms;
using TermManager.Models;
using System.Windows.Input;
using System.ComponentModel;

namespace TermManager.ViewModels
{
    public class AddCourseViewModel : INotifyPropertyChanged
    {
        public int CourseId { get; set; }
        public int TermId { get; set; }
        public string CourseTitle { get; set; }
        public DateTime StartCourseDate { get; set; }
        public DateTime EndCourseDate { get; set; }
        public string CourseStatus { get; set; }
        public string ProfessorName { get; set; }
        public string ProfessorEmail { get; set; }
        public string ProfessorPhone { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        public ICommand SaveCommand
        {
            get
            {
                return new Command((e) =>
                {
                    var item = (e as Course);

                    var test = item.CourseTitle;
                });
            }
        }

        public AddCourseViewModel()
        {
        }

        //public async void SaveNewTerm(Course course)
        //{
        //    await App.Database.SaveCourseAsync(course);
        //}
    }
}

Любая помощь, советили советы о том, как правильно реализовать захват этих полей без использования x:Name="FieldName" для заполнения модели, были бы очень благодарны.

1 Ответ

2 голосов
/ 22 октября 2019

То, что вы ищете, это Binding, который, если вы уже используете его с событиями Command и Button.

Таким же образом вы можете привязать свойства из ViewModel кПросмотр определенных свойств элементов управления.

Например, давайте возьмем один из ваших Entry:

<Entry x:Name="CourseTitle" 
    Text="{Binding CourseTitle, Mode=TwoWay}" 
    Placeholder="Course Title" 
    Margin="3" />

со свойством Text элемента Entry, о котором мы говорим: BindЗначение CourseTitle из ViewModel.

Подробнее о привязке данных можно прочитать здесь

Но для того, чтобы вышеописанное работало, вам нужно будет добавить дополнительный шаг. Ваша ViewModel уже реализует INotifyPropertyChanged, но ваши свойства должны уведомлять, когда произошло изменение его значения.

Примерно так:

public string _courseTitle;
public string CourseTitle
{
    get => _courseTitle;
    set
    {
        _courseTitle = value;
        RaisePropertyChanged(nameof(CourseTitle));
    }
}

Вы сделаете это для всех остальныхсвойства, которые вы хотите привязать к пользовательскому интерфейсу и уведомить вас об изменениях.

И добавить этот метод:

    protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

Подробнее о MVVM в Xamarin здесь

Теперь вам просто нужно добавить то же самое к остальным элементам управления в вашем пользовательском интерфейсе, соответствующем вашим свойствам ViewModel.

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="TermManager.Views.AddCourseView">
<ContentPage.Content>
    <ScrollView>
        <StackLayout>
            <Label Text="Add Course" VerticalOptions="Center" HorizontalTextAlignment="Center" IsVisible="true" FontSize="Large" FontAttributes="Bold" TextColor="DarkBlue" Margin="10" />
            <Entry x:Name="CourseTitle" Text="{Binding CourseTitle, Mode=TwoWay}" Placeholder="Course Title" Margin="3" />
            <Label Margin="3">Start Date</Label>
            <DatePicker x:Name="CourseStartDate" Margin="3" />
            <Label Margin="3">End Date</Label>
            <DatePicker x:Name="CourseEndDate" Margin="3" />
            <Picker x:Name="CourseStatus" Title="Course Status" Margin="3" TitleColor="DarkBlue">
                <Picker.ItemsSource>
                    <x:Array Type="{x:Type x:String}">
                        <x:String>in progress</x:String>
                        <x:String>completed</x:String>
                        <x:String>dropped</x:String>
                        <x:String>plan to take</x:String>
                    </x:Array>
                </Picker.ItemsSource>
            </Picker>
            <Entry x:Name="ProfessorName" Text="{Binding ProfessorName, Mode=TwoWay}" Placeholder="Professor's Name" />
            <Entry x:Name="ProfessorPhone" Text="{Binding ProfessorPhone, Mode=TwoWay}" Placeholder="Professor's Phone" />
            <Entry x:Name="ProfessorEmail" Text="{Binding ProfessorEmail, Mode=TwoWay}" Placeholder="Professor's Email" />
            <Button x:Name="SaveCourseButton" Command="{Binding SaveCommand}" Text="Save" BackgroundColor="DarkBlue" TextColor="White" Margin="3" />
            <Button Text="Cancel" BackgroundColor="DarkRed" TextColor="White" Margin="3" Clicked="CancelCourseAddition" />
        </StackLayout>
    </ScrollView>
</ContentPage.Content>

Большое примечание:

При этом вы больше не будетенужно установить значения вручную, как вы делали это в коде позади. Просто установите значения для ваших свойств в ViewModel, и они заполнят ваш вид.

Надеюсь, это поможет .-

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...