我正在创建一个带有图书库的应用程序。我可以将图书添加到图书库中,当我重新构建应用程序时,它们会正确显示。但是,我希望图书在添加后立即显示在屏幕上,并考虑使用可观察的集合来实现这一点。
我的收藏集视图:
<CollectionView ItemsSource="{Binding Books}" Margin="36, 20" Grid.Row="1">
<CollectionView.ItemTemplate>
<DataTemplate>
<Border StrokeThickness="3" Margin="0, 0, 0, 4">
<Border.Stroke>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Color="White" Offset="0.1" />
<GradientStop Color="{StaticResource Gray950}" Offset="1.0" />
</LinearGradientBrush>
</Border.Stroke>
<Grid HeightRequest="84">
<Image Aspect="AspectFill" Source="{Binding ThumbnailSource}"/>
<FlexLayout JustifyContent="Center" Direction="Column" HeightRequest="84" Margin="16">
<FlexLayout.Background>
<LinearGradientBrush EndPoint="0,1">
<GradientStop Color="#80000000" Offset="0.4"/>
<GradientStop Color="#00000000" Offset="0.9"/>
</LinearGradientBrush>
</FlexLayout.Background>
<Label FontSize="20" TextColor="White" Text="{Binding Title}" FontAttributes="Bold"/>
</FlexLayout>
</Grid>
</Border>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
我的视图模型:
namespace eBooks.ViewModel
{
public partial class LibraryViewModel : ObservableObject
{
public LibraryViewModel()
{
BookService.OnBooksChanged += RefreshLibrary;
RefreshLibrary();
}
public void RefreshLibrary(List<Book> books = null)
{
using var db = new BooksContext();
_books = new ObservableCollection<Book>(db.Books);
}
[ObservableProperty]
ObservableCollection<Book> _books;
}
}
我的书模型
namespace eBooks.Models
{
[Table("Books")]
public class Book
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Title { get; set; }
public double Progress { get; set; }
public string ThumbnailData { get; set; }
public string AudioData { get; set; }
public string ThumbnailFormat { get; set; }
public string AudioFormat { get; set; }
private byte[] _thumbnailData = null;
public ImageSource ThumbnailSource
{
get
{
if (_thumbnailData == null || _thumbnailData.Length == 0 && ThumbnailData.Length != 0)
_thumbnailData = Convert.FromBase64String(ThumbnailData);
return ImageSource.FromStream(() => new MemoryStream(_thumbnailData));
}
}
}
}
处理EF Core数据库层操作的服务:
namespace eBooks.Services
{
public class BookService
{
public delegate void BooksChanged(List<Book> books);
public static event BooksChanged OnBooksChanged;
public void Add(Book book)
{
using var db = new BooksContext();
db.Books.Add(book);
db.SaveChanges();
OnBooksChanged?.Invoke(db.Books.ToList());
}
public void Delete(int id)
{
using var db = new BooksContext();
db.Books.Remove(db.Books.Single(book => book.Id == id));
db.SaveChanges();
OnBooksChanged?.Invoke(db.Books.ToList());
}
}
}
我尝试添加一个'refreshlibrary'方法,当在book服务中调用OnBooksChanged
事件时运行,如上面的代码所示。通过向该方法添加断点,我可以看到添加后它包含新添加的图书,但UI仍然不显示该图书。
1条答案
按热度按时间n6lpvg4x1#
在您的示例中,
ObservableCollection
与简单的List
相比没有任何优势。ObservableCollection
的优势在于,如果您操作集合的内容,它将通知对其绑定到的控件的更改。在这里,您不是在操作_books
的内容,你每次都给一个新的示例,所以我们假设一开始你有_books
中的(Book1, Book2)
,我们把这个集合命名为A
,如果Book3
被添加到你的数据库中,你要给_books
赋值一个新的集合(Book1, Book2, Book3)
,我们把这个新的集合命名为B
,注意你没有把Book3
添加到A
,现在你的CollectionView
仍然绑定到A
,A
没有改变,因此不会收到更新通知。您需要做的就是确保CollectionView
重新评估其绑定并绑定到B
。有几种方法可以做到这一点:1.设置generated属性而不是支持字段,因为它将自动调用
OnPropertyChanged
:1.呼叫
OnPropertyChanged
:同样,您可以安全地将
_books
的类型更改为List<Book>
,因为在任何地方都不会对它进行操作。