如何将ListView绑定到集合并实时刷新

时间:2019-06-24 07:50:49

标签: c# listview xamarin mvvm xamarin.forms

我将ListView绑定到我的Realm数据库,但是当我向其中添加新项时它不会刷新它。我正在使用另一页添加新项目。

我在这里用作参考:https://help.syncfusion.com/xamarin/sflistview/mvvm#binding-itemssource

我的模特:

public class Category : RealmObject
    {
        [PrimaryKey]
        public string CategoryID { get; set; } = Guid.NewGuid().ToString();

        public string CategoryTitle { get; set; }

        public string CategoryDetails { get; set; }

        [Backlink(nameof(Note.CategoryOfNote))]
        public IQueryable<Note> Notes { get; }

        public string CategoryIcon { get; set; }
        public bool IsExpanded { get; set; }
    }

我的包含ListView的XAML文件

<ContentPage.BindingContext>
        <vm:MainViewModel />
    </ContentPage.BindingContext>
    <ContentPage.ToolbarItems>
        <ToolbarItem Text="NEWCAT" 
                     Clicked="NewCat_Clicked"/>
    </ContentPage.ToolbarItems>

    <ContentPage.Content>

        <ListView x:Name="categoryList"
                  ItemsSource="{Binding Categories}"
                  ItemTapped="ListView_ItemTapped"
                  HasUnevenRows="True">

            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Orientation="Vertical" 
                                     HorizontalOptions="FillAndExpand"
                                     Padding="10"
                                     Spacing="10">
                            <Label Text="{Binding Path=CategoryTitle}" 
                                   FontSize="Medium"/>
                            <StackLayout IsVisible="{Binding IsExpanded}" 
                                         Orientation="Horizontal"
                                         HorizontalOptions="CenterAndExpand">
                                <Button Text="Notes"
                                        Clicked="NotesButton_Clicked" />
                                <Button Text="Edit" 
                                        Clicked="EditButton_Clicked"/>
                                <Button Text="Delete"
                                        Clicked="DeleteButton_Clicked"/>
                            </StackLayout>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ContentPage.Content>

还有我的ViewModel (DBServices.GetCategories是一个静态方法,该方法从Realm DB返回类别的集合。BaseViewModel实现INotifyPropertyChanged)

class MainViewModel : BaseViewModel
    {

        private Category _oldCategory;
        public MainViewModel()
        {
            RefreshCategories();
        }

        private void RefreshCategories()
        {
            Categories = new ObservableCollection<Category>(DBServices.GetCategories());
        }


        private ObservableCollection<Category> _Categories;
        public ObservableCollection<Category> Categories
        {
            get
            {
                return _Categories;
            }
            set
            {
                _Categories = value;
                OnPropertyChanged("Categories");
            }
        }
    }

这是BaseViewModel类中的OnPropertyChanged方法

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

当我单击工具栏按钮时,它会推送一个新的表单页面以创建一个新类别。然后,仅将该类别添加到Realm DB。之后它会自动弹出。但是我看不到ListView发生变化。

编辑:重新启动应用程序后,我可以在ListView中看到新项目。但是我希望在添加它们时将其列出。

2 个答案:

答案 0 :(得分:0)

要仅测试XAML和ViewModel,请尝试在ViewModel中将DBServices.GetCategories()替换为以下内容:

public static IEnumerable<Category> TestCategories
{
    get
    {
        yield return new Category { CategoryTitle = "title 1" };
        yield return new Category { CategoryTitle = "title 2" };
    }
}
...
public MainViewModel()
{
    Categories = new ObservableCollection<Category>(TestCategories);
}

DBServices.GetCategories()也应该测试预期的输出,此处未显示。

答案 1 :(得分:0)

您可以使用Xamarin表单MessagingCenter告诉ListView它需要更新。

在将新类别添加到Realm DB的页面上,在添加类别之后但在弹出页面之前的某个时候,您将发送一条消息,通知ListView页面进行更新。看起来可能像这样:

MessagingCenter.Send(this, "Update listview");

在MainViewModel中,您需要订阅该消息,然后对其进行操作。可能是这样的:

MessagingCenter.Subscribe<AddCategoryPage>(this, "Update listview", (sender) =>
{
    RefreshCategories();
});

使用MessagingCenter时要注意的两个项目。

  1. 传递的消息在发送者和订阅者之间必须相同。在这种情况下,消息为“更新列表视图”。因为必须相同,所以您可能希望在单独的类中定义消息,以便发送方和订阅方都可以引用它。
  2. 订阅消息时,必须确保您取消订阅。一种流行的模式是在页面出现时进行订阅,而在页面消失时取消订阅。不过,不同的模式可能更适合您。

附带说明,您不需要Categories的完整属性定义。 ObservableCollection将在添加或删除项目时处理通知。只需设置一次Categories = new ObservableCollection<Category>();,然后仅添加或删除项。您无需在每次数据库调用时都进行更新。