【问题标题】:Problem of Xamarin.Form (ListView not refresh if binding from Akavache cache)Xamarin.Form 问题(如果从 Akavache 缓存绑定,ListView 不会刷新)
【发布时间】:2020-05-29 10:15:37
【问题描述】:

我遇到了刷新列表的问题。

我在 Visual Studio 2019 (Xamarin.Forms 4.3.0.991250) 和 Akavache 6.6.1 中使用带有 init 默认值的 MasterDetailPage,变量是 ObservableCollection<TodoItem> 类型的项目。

首先,我向缓存中添加了一个项目(我称这个对象为 TodoItem)。然后显示 ListView 与从 Akavache 缓存获取的 Items 绑定,但它不起作用,Items 有值 -> ListView 不刷新。

我尝试了一些东西:

  • 更改版本(Xamarin.Forms 和 Akavache),例如:XF 4.1 最高版本和 akavache 降级 6.0、6.1、6.2... => 不起作用。

  • 如果使用硬编码 new ObservableCollection(new ListView(){ ... }) => 设置项目,它可以工作。

  • 如果应用程序正在运行,我会更改布局并保存(Xaml 热重载)-> 它正在运行。

    public ObservableCollection Items { get;放; } = 新的 ObservableCollection();

    #region AddNewCommand
    
    private Command _addNewCommand;
    
    public Command AddNewCommand =>
        _addNewCommand ?? (_addNewCommand = new Command(async (p) => await AddNewExecute(), (p) => !IsBusy));
    
    private async Task AddNewExecute()
    {
        var key = Guid.NewGuid().ToString().Substring(0, 5);
        await BlobCache.LocalMachine.InsertObject<TodoItem>(key, new TodoItem() {Id=key.Substring(0,2),Text="abc",Description="def" }, new TimeSpan(1, 0, 0));
        var list = await BlobCache.LocalMachine.GetAllObjects<TodoItem>();
        Items = new ObservableCollection<TodoItem>(list);
    }
    #endregion
    

【问题讨论】:

  • 请不要将代码发布为图片
  • 请把代码包装在你的 AddNewExecute 里面,Device.BeginInvokeOnMainThread (() => { //你的代码放在这里 });
  • 您需要发布您的 xaml 和 Items 属性。
  • 谢谢@ottermatic,我正在尝试稍后转发结果...

标签: listview xamarin akavache


【解决方案1】:

为了对 UI 的变量绑定端进行更改,您必须在 BeginInvokeOnMainThread 中进行此操作

类似这样的:

private async Task AddNewExecute()
{
     var key = Guid.NewGuid().ToString().Substring(0, 5);
     await BlobCache.LocalMachine.InsertObject<TodoItem>(key, new TodoItem() 
        {
          Id=key.Substring(0,2),Text="abc",Description="def" }, new TimeSpan(1, 0, 0));
          Device.BeginInvokeOnMainThread (async () => {
          var list = await BlobCache.LocalMachine.GetAllObjects<TodoItem>();
          Items = new ObservableCollection<TodoItem>(list);
        });
}

通过这种方式,您正在更改 UI 线程上的变量

【讨论】:

  • Tks @Adrián Romero,但是这段代码失败了,Device.BeginInvokeOnMainThread 不能在新的 TodoItem() 块内。???
  • 为什么会失败? (你能看到我的编辑吗?)我刚刚添加了一个等待
猜你喜欢
  • 1970-01-01
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-30
  • 2014-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多