【问题标题】:MVVMCross - Updating A UITableView SourceMVVMCross - 更新 UITableView 源
【发布时间】:2014-01-16 15:16:52
【问题描述】:

我有一个在加载时绑定到视图的列表,它工作正常。我还有一个计时器,它调用服务来检查要添加到列表中的任何新项目。当我尝试将新项目添加到列表时出现问题,我收到一个错误,需要在 UI 线程上完成。

我正在尝试将项目添加到 ObservableCollection 中,如下所示:

private ObservableCollection<ChatMessageViewModel> _items;

public MyViewModel(IMvxMessenger messenger, IMyService myService) : base (messenger)
    {
        _myService = myService;
        _timer = new Timer(GetLatestItems,null, 1000,10000);
    }


public async void GetLatestItems()
    {
       var newItems = await _myService.GetNewMessages();
        if (newItems != null && newItems.Count > 0)
        {
            foreach (var item in newItems)
            {
                Items.Add(item);
            }
        }
    }

【问题讨论】:

    标签: xamarin.ios xamarin mvvmcross


    【解决方案1】:

    ObservableCollection/INotifyCollectionChanged 必须同步使用 - 所以你必须在 UI 线程上使用它。

    Timer 使用 ThreadPool 线程。

    要将调用编组回 UI,请尝试以下操作:

    public MyViewModel(IMvxMessenger messenger, IMyService myService) : base (messenger)
    {
        _myService = myService;
        _timer = new Timer(GetLatestItems,null, 1000,10000);
    }
    
    public async void GetLatestItems()
    {
       var newItems = await _myService.GetNewMessages();
       InvokeOnMainThread(() => {
        if (newItems != null && newItems.Count > 0)
        {
            foreach (var item in newItems)
            {
                Items.Add(item);
            }
        }
     });
    

    【讨论】:

    • 或者在现代世界的 async/await 中:async void FunkyTimer() { while (true) { await Task.Delay(10000); await GetLatestItems(); } } 并且对 InvokeOnMainThread 的需求已经消失。 (灵感来自@StephaneDelcroix)
    • 为此+1...虽然我会小心while (true)的退出条件
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多