首页 > 解决方案 > 绑定到 ListView 的 Xamarin.Forms 列表有时会短暂显示元素,然后一切都消失了

问题描述

我按照microsoft的文档创建了一个带有本地数据库的多页应用程序,该数据库显示了简短的注释。但是,这并不遵循 MVVM。所以我尝试重构代码以符合 MVVM 设计。

在我的 App.xaml.cs 文件中,我为 MainPage 创建了一个 NavigationPage,它是一个 ContentPage,其中包含注释列表的 ContentView。我通过将笔记写入运行正常的调试器来测试我的笔记是否正确加载。我的 NotesView.xaml 是这样的:

...
    <ContentView.BindingContext>
        <viewModel:NotesViewModel />
    </ContentView.BindingContext>
    
    <ContentView.Content>
        <StackLayout>
            <ListView Margin="{StaticResource PageMargin}"
                    ItemsSource="{Binding Notes}"
                    SelectedItem="{Binding SelectedNote}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextCell Text="{Binding Text}"
                                  Detail="{Binding Date}" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentView.Content>
</ContentView>

我的笔记视图模型:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Threading.Tasks;
using AwesomeApp.Models;

namespace AwesomeApp.ViewModels
{
    class NotesViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public NotesViewModel()
        {
            notes = new List<Note>();
            _selectedNote = new Note();
            LoadNotes();
        }

        private Note _selectedNote;
        public Note SelectedNote
        {
            get
            {
                return _selectedNote;
            }
            set
            {
                if (_selectedNote != value)
                {
                    _selectedNote = value;
                }
            }
        }

        List<Note> notes;
        public List<Note> Notes
        {
            set
            {
                if (value != notes)
                {
                    notes = value;
                    OnPropertyChanged("Notes");
                }
            }
            get
            {
                return notes;
            }
        }
        public async void LoadNotes()
        {
            notes = await App.Database.GetNotesAsync();

            foreach (var note in Notes)
            {
                System.Diagnostics.Debug.WriteLine("Notes: {0},{1},{2}", note.ID, note.Text, note.Date);
            }

        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

我的模型 Notes 包含三个属性:

public class Note : INotifyPropertyChanged
    {
        private int id;
        private string text;
        private DateTime date;
...

当我现在尝试显示包含列表中项目的 ListView 时,这些项目非常短暂地出现然后消失。只有在我进行布局更改并保存它们以便在 android 9.0 手机上调试期间触发 HotReload 时重新构建应用程序时,才会显示元素。

标签: c#xamarin.forms

解决方案


由于无法运行/调试您的应用程序,我发现了一些错误,我认为这些错误正在造成这些问题。

1-将构造函数更改为:

public NotesViewModel()
{
    LoadNotes();
}

如果你想选择一个笔记,不要将一个新的实例化为_selectedNote = new Note();. 所选注释必须指向Notes列表中的注释。

2-在LoadNotes()你必须做的:

Notes = await App.Database.GetNotesAsync();

请记住始终使用属性而不是私有字段。既然你这样做notes = ...了,该属性就不会触发OnPropertyChanged("Notes");. 所以你要么必须这样做:

notes = await App.Database.GetNotesAsync();
OnPropertyChanged("Notes");

或更好):

Notes = await App.Database.GetNotesAsync();

3-你的模型类,不应该实现INotifyPropertyChanged接口,它应该直接类似于:

public class Note {
    private int id;
    private string text;
    private DateTime date;
}

在任何情况下,您都可以让您的 ViewModel 进行此类欺骗,并通知您的 View 有关 ViewModel 数据的更改。


推荐阅读