ListView ItemsSource绑定不显示项目

时间:2016-10-12 14:00:03

标签: c# listview xamarin xamarin.forms

我正在尝试在Xamarin中创建绑定的ListView。这是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" });
    }
}

您还可以看到一些带有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 个答案:

答案 0 :(得分:1)

我不确定ContentPage是否将[CallerMemberName]用于OnPropertyChanged()方法。所以我首先要尝试的是写OnPropertyChanged("Items")

无论哪种方式,如果我是你,我会分离关注点并将项目移动到ViewModel类中,该类实现INotifyPropertyChanged本身。如果您想测试,添加更多代码(如命令,注入依赖项等),这将有助于以后将ViewModel代码与View代码分开。

所以你可以从:

开始
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);
        });
    }
}

然后,您可以将View代码保持为:

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

通常,您将调用命令来填充ViewModel中的Items,这可以是从Internet获取数据,或从数据库中加载本地数据等。

在此示例中,您只需向LearnViewModel添加构造函数,并多次调用DoAddTodoItem

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

当你启动应用程序时,这应该会显示这样的内容:

enter image description here