Где я должен разместить свою собственность, не нарушая шаблон MVVM? - PullRequest
1 голос
/ 23 февраля 2020

Я новичок в Xamarin и шаблоне MVVM, и у меня есть простое приложение, которое должно отображать контакты в списке.

Теперь мой вид отображает фамилию контакта и его номер. Хорошо, отлично! Теперь я хотел бы, чтобы отображались Фамилия и Имя. Конечно, я мог бы изменить свою модель, чтобы она содержала свойство, называемое public string FullName, и заполняла его. Но я думаю, что это не в духе шаблона, верно?

Где я должен отражать что-то подобное, не нарушая схему? Только в представлении и XAML-файле, используя что-то вроде <MultiBinding />? Или мой ViewModel должен содержать дополнительные свойства?

Это мой код:

Модель:

public class Contact
{
    public string Id { get; set; }

    public string Surname { get; set; }

    public string Lastname { get; set; }

    public string Number { get; set; }
}

ViewModel:

public class ContactsViewModel : ViewModelBase
{
    public ObservableCollection<Contact> Contacts { get; set; }

    public Command LoadContacts { get; set; } 

    public ContactsViewModel()
    {
        this.Title = "List of contacts";
        Contacts = new ObservableCollection<Contact>();
        LoadContacts = new Command(async () => await LoadContactsFromDataStore());
    }

    private async Task LoadContactsFromDataStore()
    {
        var contacts = await ContactDataStore.GetItemsAsync(true);

        foreach (var contact in contacts)
        {
            Contacts.Add(contact);
        }
    }
}

И мой базовый класс

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public string Title { get; set; }

    public IContactDataStore<Contact> ContactDataStore => DependencyService.Get<IContactDataStore<Contact>>();

    public event PropertyChangedEventHandler PropertyChanged;

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

Вид:

<ContentPage.ToolbarItems>
    <ToolbarItem Text="New Contact" Clicked="AddContact_Clicked"/>
</ContentPage.ToolbarItems>

<StackLayout>
    <ListView x:Name="ContactsListView"
              ItemsSource="{Binding Contacts}"
              VerticalOptions="FillAndExpand"
              HasUnevenRows="True"
              ItemSelected="OnItemSelected">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Padding="10">
                        <Label Text="{Binding Lastname}" FontSize="16"></Label>
                        <Label Text="{Binding Number}" FontSize="13"></Label>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>            
</StackLayout>

Код позади:

[DesignTimeVisible(false)]
public partial class ContactsPage : ContentPage
{
    private readonly ContactsViewModel contactsViewModel;

    public ContactsPage()
    {
        InitializeComponent();

        BindingContext = contactsViewModel = new ContactsViewModel();
    }

    private async void OnItemSelected(object sender, SelectedItemChangedEventArgs args)
    {
        if (!(args.SelectedItem is Contact contact))
            return;

        await Navigation.PushAsync(new ContactDetailPage(new ContactDetailViewModel(contact)));

        ContactsListView.SelectedItem = null;
    }

    private async void AddContact_Clicked(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();

        if (contactsViewModel.Contacts.Count == 0)
        {
            contactsViewModel.LoadContacts.Execute(null);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...