Привязка к источнику элементов ListView не отображает элементы

#c# #listview #xamarin #xamarin.forms

#c# #listview #xamarin #xamarin.forms

Вопрос:

Я пытаюсь создать связанный ListView в Xamarin. Вот код C #:

 public partial class LearnPage : ContentPage
{
    public class TodoItem
    {
        public string DisplayName { get; set; }
    }

    //ObservableCollection<TodoItem> Items = new ObservableCollection<TodoItem>();
    private IEnumerable<TodoItem> _items;
    public IEnumerable<TodoItem> Items
    {
        get { return _items; }
        set
        {
            if (Equals(_items, value))
                return;
            _items = value;
            OnPropertyChanged();
        }
    }

    public LearnPage ()
    {
        InitializeComponent();
        BindingContext = this;
        Items = new TodoItem[]{
            new TodoItem{ DisplayName = "Milk cartons are recyclable" }
        };
        //Items.Add(new TodoItem { DisplayName = "Milk cartons are recyclable" });
    }
}
  

Вы также можете увидеть некоторый закомментированный код с помощью an ObervableCollection , с которым я также пробовал.

И вот XAML:

 <?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="learn.LearnPage">
<ContentPage.Content>
    <StackLayout VerticalOptions="FillAndExpand" Padding="0,10,0,10">
        <ListView ItemsSource="{Binding Items}" RowHeight="40" x:Name="sarasas">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextCell Text="{Binding DisplayName}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage.Content>
  

Когда я создаю приложение, отображается пустой список. Я действительно новичок в Xamarin, и я думаю, что я просто упускаю что-то очевидное. Любая помощь приветствуется!

Комментарии:

1. Это случилось со мной, и я попытался присвоить списку n другой способ, попробуйте это: var list = new TodoItem[]{ new TodoItem{ DisplayName = «Коробки из-под молока подлежат вторичной переработке» } }; Items = list; Посмотрим, поможет ли это

2. Спасибо за совет, однако проблема сохраняется.

Ответ №1:

Я не уверен, использует ли ContentPage [CallerMemberName] для этого OnPropertyChanged() метода. Итак, первое, что я бы попробовал, это написать OnPropertyChanged("Items") вместо этого.

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

Итак, вы могли бы начать с:

 public abstract class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

Затем создайте свою ViewModel:

 public class LearnViewModel : BaseViewModel
{
    public ObservableCollection<TodoItem> Items { get; } = new ObservableCollection<TodoItem>();

    private ICommand _addTodoItem;
    public ICommand AddTodoItem => 
        _addTodoItem = _addTodoItem ?? new Command(DoAddTodoItem);

    private int _count;
    private void DoAddTodoItem()
    {
        var item = new TodoItem { DisplayName = $"Item {  _count}" };
        // NotifyCollectionChanged must happen on UI thread.
        Device.BeginInvokeOnMainThread (() => {
             Items.Add(item);
        });
    }
}
  

Тогда вы можете сохранить свой код представления тонким, например:

 public partial class LearnPage : ContentPage
{
    public LearnPage ()
    {
        InitializeComponent();
        BindingContext = new LearnViewModel();
    }
}
  

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

В этом примере вы можете просто добавить конструктор в LearnViewModel и вызвать DoAddTodoItem пару раз:

 public class LearnViewModel : BaseViewModel
{
    public LearnViewModel()
    {
        DoAddTodoItem();
        DoAddTodoItem();
    }
    ...
  

Это должно показать вам что-то вроде этого при запуске приложения:

введите описание изображения здесь

Комментарии:

1.Он использует [CallerMemberName] github.com/xamarin/Xamarin .Forms/blob/master/Xamarin.Forms.Core/…

2. Спасибо за ответ, он очень сложный. Мне придется потратить некоторое время на понимание этого, так как есть некоторые неизвестные синтаксисы и приемы. Я свяжусь с вами, если у меня возникнут дополнительные вопросы или я не смогу заставить его работать!