ReactiveUI ReactiveCommand和Xamarin 4.0 Shell导航

时间:2019-06-22 22:20:42

标签: xamarin xamarin.forms xamarin.ios reactiveui

使用具有新Shell功能的Xamarin Forms 4.0,我在页面上有一个按钮。让我们将此页面称为起始页面

当我按下按钮时,用户使用Shell.Current.GoToAsync导航到第二页

当用户稍后导航回到起始页时,该按钮将被停用。但是为什么呢?

这是视图模型中的代码:

public class SomeViewModel : ReactiveObject
{
   private ReactiveCommand<Unit, Unit> _someCommand;

   public ReactiveCommand<Unit, Unit> SomeCommand
   {
      get => _someCommand;
      set => this.RaiseAndSetIfChanged(ref _someCommand, value);
   }

   public SomeViewModel
   {

      SomeCommand = ReactiveCommand.CreateFromTask<Unit>(async x =>
      {
          await Shell.Current.GoToAsync("//Root/SomePage");
      }).Subscribe();

}

通过反复试验,我找到了解决方法。

具体来说,通过对SomeCommand的定义进行以下更改,当用户返回起始页

时,该按钮将不再被禁用:
[...]
   SomeCommand = ReactiveCommand.CreateFromTask<Unit>(async x =>
      {
          await Task.CompletedTask;
      })
     .Select(_ => Observable.FromAsync(() => Shell.Current.GoToAsync("//Root/SomePage")}")))
     .Concat()
     .Subscribe();
[...]

任何人都可以解释这里发生的事情吗?为什么第一种方法不起作用,为什么第二种方法起作用?在我看来,这两种方法大致相同。

我正在使用ReactiveUI版本v9.17.4。到目前为止,我仅在iOS上进行了测试。

更新:原来是线程问题。

1 个答案:

答案 0 :(得分:0)

使用互动


import jira.client
from jira.client import JIRA

options = {'server': 'https://hostname.net'}
jira = JIRA(options, basic_auth=('user_id', 'password'))


block_size = 100
block_num = 0
allissues = []
while True:
    start_idx = block_num*block_size
    issues = jira.search_issues('project=abc', start_idx, block_size)
    if len(issues) == 0:
        # Retrieve issues until there are no more to come
        break
    block_num += 1
    for issue in issues:
        print('%s: %s' % (issue.key, issue.fields.summary))
        allissues.append(issue)
    if block_num > block_size:
        break

然后,在AppShell构造函数中:

public static class Interactions
{
    public static readonly Interaction<string, Unit> Navigate = new Interaction<string, Unit>();
}

并在您的ViewModel构造函数中:

Interactions.Navigate.RegisterHandler(async context =>
{
    await Current.GoToAsync(context.Input);
    context.SetOutput(Unit.Default);
}