Добавить несколько обязательных контекста в файл xaml - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь реализовать свой первый MVVM-проект. Сначала я создал модель под названием "person.cs". Затем я создал представление модели «AddPerson.cs», которое должно динамически создавать данные, которые хранятся в person.cs. На мой взгляд (полностью создан с помощью xaml) у меня есть кнопка, которая должна вызывать метод «CreatePerson ()» из моего «AddPerson.cs». Мне нравится связывать метод.

Кроме того, я создал метку, которая должна быть привязана к классу "person.cs", например, к общедоступной строке "Имя".

Как я могу установить BindingContext кнопки для класса "AddPerson.cs" и BindingContext метки для класса "person.cs"?

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Вам не хватает некоторых важных понятий, из-за которых ваши запросы выглядят странно.

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

Таким образом, ваша ViewModel должна выглядеть примерно так:

public class PersonViewModel
{
   public Person Person {get; set}
   public ICommand AddPersonCommand {get; set}
}

Ваш BindingContext является тогда экземпляром PersonViewModel, а затем на ярлыке вы связываетесь с Person, в то время как на кнопке вы привязываете к AddPersonCommand.

0 голосов
/ 08 января 2019

Да, это возможно. Большинство элементов наследуют BindablObject. Каждый BindableObjaect имеет свойство BindingContext. Смотри: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-binding-basics

MainViewModel

Viewmodel для всей вашей страницы, которая содержит каждую подвидовую модель.

public class MainViewModel
{
    public AddPersonViewModel AddPersonViewModel { get; }
    public PersonViewModel PersonViewModel { get; }

    public MainViewModel()
    {
        // the passed action is just a fake action to simulate adding a person
        AddPersonViewModel = new AddPersonViewModel(value => PersonViewModel.Name = value);
        PersonViewModel = new PersonViewModel();
    }
}

AddPersonViewModel

Содержит вашу логику добавления.

public class AddPersonViewModel : INotifyPropertyChanged
{ 
    public AddPersonViewModel(Action<string> onAction)
    {
        AddPerson = new Command(() => 
        {
            onAction(NewName); // call your update logic
            NewName = ""; // reset name
        });
    }

    public Command AddPerson { get; }
    private string _name;

    public string NewName
    {
        get => _name;
        set
        {
            _name = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(NewName)));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

PersonViewModel

Содержит ваш "новый" Персона.

public class PersonViewModel : INotifyPropertyChanged
{
    private string _name;

    public string Name
    {
        get => _name;
        set
        {
            _name = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

MainPage

Создайте и настройте свою MainViewModel.

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        BindingContext = new MainViewModel();
    }
}

MainPage.xaml

Здесь мы связываем BindingContext из Entry и Button со свойством AddPersonViewModel нашего ContentPage's BindingContext, которое является MainViewModel. И затем мы связываем Text из Label и Command из Button с NewName и AddPerson локальных BindingContext, что составляет AddPersonViewModel

То же самое для Label.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:App5"
             x:Class="App5.MainPage">

    <StackLayout>
        <Entry BindingContext="{Binding AddPersonViewModel}" Text="{Binding NewName}" 
           HorizontalOptions="FillAndExpand" />
        <Button BindingContext="{Binding AddPersonViewModel}" Text="Click me!" Command="{Binding AddPerson}" 
           HorizontalOptions="Center" />
        <Label Text="Added Person:" FontAttributes="Bold" 
           HorizontalOptions="Center"/>
        <Label BindingContext="{Binding PersonViewModel}" Text="{Binding Name}" 
           HorizontalOptions="Center"/>
    </StackLayout>

</ContentPage>

Пример очень хакерский, но я думаю, вы поняли. Ключ уже упоминавшегося свойства BindingContext

...