[英]How to bind ListView to a collection and refresh it real time
I am binding my ListView to my Realm database, but it doesn't refresh it when I add a new item into it. 我将ListView绑定到我的Realm数据库,但是当我向其中添加新项时它不会刷新它。 I am adding new items using another page.
我正在使用其他页面添加新项目。
I am using here as reference: https://help.syncfusion.com/xamarin/sflistview/mvvm#binding-itemssource 我在这里用作参考: https : //help.syncfusion.com/xamarin/sflistview/mvvm#binding-itemssource
My Model: 我的型号:
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; }
}
My XAML file containing ListView 我的XAML文件包含ListView
<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>
And my ViewModel (DBServices.GetCategories is a static method that returns a collection of categories from Realm DB. And BaseViewModel implements INotifyPropertyChanged) 而我的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");
}
}
}
This is OnPropertyChanged method in BaseViewModel class 这是BaseViewModel类中的OnPropertyChanged方法
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
When I click to the toolbar button, it pushes a new form page to create a new category. 当我单击工具栏按钮时,它会推送一个新的表单页面来创建一个新类别。 Then it just adds that category to the Realm DB.
然后它只是将该类别添加到Realm DB。 Afterwards it pops itself.
然后它弹出自己。 But I see no change in my ListView.
但我看到我的ListView没有变化。
EDIT: I can see new items in ListView when I restarted the app. 编辑:当我重新启动应用程序时,我可以在ListView中看到新项目。 But I want it to be listed as I add them.
但我希望它在我添加它时列出。
To test the XAML and ViewModel only, try replacing DBServices.GetCategories()
with the following in the ViewModel: 要仅测试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()
should also be tested for expected output, not shown here. 还应测试
DBServices.GetCategories()
的预期输出,此处未显示。
You could use the Xamarin Forms MessagingCenter to tell the ListView it needs to update. 您可以使用Xamarin Forms MessagingCenter告诉它需要更新的ListView。
On the page where the new category is added to the Realm DB, at some point after the category is added but before the page is popped, you would send a message to tell the ListView page to update. 在将新类别添加到Realm DB的页面上,在添加类别之后但在弹出页面之前的某个时刻,您将发送一条消息以告知ListView页面更新。 This may look something like:
这看起来像是这样的:
MessagingCenter.Send(this, "Update listview");
In your MainViewModel you'll need to subscribe to the message and then act upon it. 在您的MainViewModel中,您需要订阅该消息,然后对其进行操作。 This could be something like:
这可能是这样的:
MessagingCenter.Subscribe<AddCategoryPage>(this, "Update listview", (sender) =>
{
RefreshCategories();
});
Two items to note when using the MessagingCenter. 使用MessagingCenter时需要注意两个事项。
On a side note, you shouldn't need the full property definition for Categories
. 另外,您不应该需要
Categories
的完整属性定义。 The ObservableCollection
will handle the notification when items are added or removed. ObservableCollection
将在添加或删除项目时处理通知。 Just set Categories = new ObservableCollection<Category>();
只需设置
Categories = new ObservableCollection<Category>();
once and then only add or remove items. 一次然后只添加或删除项目。 You don't need to new it up on every DB call.
您无需在每次数据库调用时重新启动它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.