我正在尝试在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来说真的很陌生,我想我只是错过了一些明显的东西。任何帮助表示赞赏!
答案 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();
}
...
当你启动应用程序时,这应该会显示这样的内容: